简体   繁体   English

春季无法获取keycloak授权令牌

[英]Can not get keycloak authorization token in spring

I have web application which and i am trying to make keycloak authorizations on JavaScript side I am going on keycloak login page and authenticating successfully.我有一个 Web 应用程序,我正在尝试在 JavaScript 端进行keycloak authorizations ,我将进入keycloak登录页面并成功进行身份验证。 Here is my code这是我的代码

var keycloak = Keycloak({
            realm: 'demo',
            url: 'localhost:8080/auth',
            clientId: 'justice'
        });
        keycloak.init({ onLoad: 'login-required' }).success(function(authenticated) {
            alert(authenticated ? 'authenticated' : 'not authenticated');
        }).error(function() {
            alert('failed to initialize');
        });

then I am calling Rest web service on java side然后我在java端调用Rest web service

$.ajax({
                    type: "POST",
                    url: "login",
                    headers: {
                        "Authorization":"Bearer "+ keycloak.token
                    },
                    success: function (response) {
                        location.reload();

                    },
                    error: function (jqXHR, textStatus, errorThrown) {
                        console.log(textStatus, errorThrown);
                    }
                });

Here is everything okay, I am taking token and putting in header,But I have problem on java side, Can not take this authorization token , user role and some other properties from this token .这里一切正常,我正在获取令牌并放入标头,但我在 Java 方面有问题,无法从该token获取此authorization tokenuser role和其他一些properties

Here is my configuration class which uses spring security config这是我的configuration类,它使用spring security config

import javax.servlet.http.HttpServletRequest;
import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.client.KeycloakClientRequestFactory;
import org.keycloak.adapters.springsecurity.client.KeycloakRestTemplate;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.keycloak.representations.AccessToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@KeycloakConfiguration
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

    @Autowired
    KeycloakClientRequestFactory keycloakClientRequestFactory;

    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new NullAuthenticatedSessionStrategy();
    }

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public KeycloakRestTemplate keycloakRestTemplate() {
        return new KeycloakRestTemplate(keycloakClientRequestFactory);
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
        keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
        auth.authenticationProvider(keycloakAuthenticationProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .sessionAuthenticationStrategy(sessionAuthenticationStrategy()).and().authorizeRequests()
                .antMatchers("/login*").hasRole("ADMIN").anyRequest().permitAll();
    }

    @Bean
    @Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
    public AccessToken getAccessToken() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
                .getRequest();
        return ((KeycloakAuthenticationToken) request.getUserPrincipal()).getAccount().getKeycloakSecurityContext()
                .getToken();
    }

}

Then I am trying to take token but every try is useless.然后我试图拿令牌,但每次尝试都是无用的。

I tried this way and result is null我试过这种方式,结果为空

@Controller
@RequestMapping
public class AuthController {

    @Autowired
        private AccessToken accessToken;

     @RequestMapping(value = "/login", method = {RequestMethod.POST})
public String verify(Principal principal,Model model) throws Exception {
     //principal field is null
    String token = accessToken.getAccessTokenHash(); // null
}

and this way这样

@Controller
@RequestMapping
public class AuthController {

    @Autowired
        private AccessToken accessToken;

     @RequestMapping(value = "/login", method = {RequestMethod.POST})
public String verify(Principal principal,Model model) throws Exception {
     Authentication auth =SecurityContextHolder.getContext().getAuthentication();
    KeycloakPrincipal principal = (KeycloakPrincipal) auth.getPrincipal(); // again null 
}

and this way also这样也

@Controller
    @RequestMapping
    public class AuthController {

        @Autowired
            private AccessToken accessToken;

         @RequestMapping(value = "/login", method = {RequestMethod.POST})
    public String verify(Principal principal,Model model) throws Exception {
         HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
                .getRequest();

 KeycloakSecurityContext keycloakSecurityContext = (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
                AuthorizationContext authzContext = keycloakSecurityContext.getAuthorizationContext(); // and still null
}

here is content of my keycloak.json which is placed in WEB-INF这是我放在WEB-INF keycloak.json内容

{
  "realm": "demo",
  "bearer-only": true,
  "auth-server-url": "localhost:8080/auth",
  "ssl-required": "external",
  "resource": "justice-service",
  "use-resource-role-mappings": true
}

Maybe I misunderstand flow of this authentication or something.Maybe I have some mistakes in code or in configuration .也许我误解了这个authentication流程什么的。也许我在代码或configuration有一些错误。 I just need to take token and properties from this token ie user role or username on java side.我只需要从这个令牌中获取tokenproperties ,即 Java 端的用户角色或用户名。 I am using first time keycloak authentication , anyway do I need to set this Adapters on JavaScript and on Java side too like I have ?我第一次使用keycloak authentication ,无论如何我是否需要像我一样在JavaScriptJava端设置这个Adapters Or is it enough to have only in JavaScript ?还是仅在JavaScript就足够了?

I am not using spring boot or any of it's libraries .我没有使用spring boot或其任何libraries

Here is my pom.xml libraries这是我的pom.xml libraries

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <log4j.version>1.2.17</log4j.version>
        <spring.version>4.2.5.RELEASE</spring.version>
        <spring.security.version>4.2.5.RELEASE</spring.security.version>
        <java.version>1.8</java.version>
        <org.jooq.version>3.7.3</org.jooq.version>
        <org.h2.version>1.4.181</org.h2.version>
        <org.postgresql.version>9.4-1201-jdbc41</org.postgresql.version>
    </properties>



    <dependencies>
        <dependency>
            <groupId>org.jooq</groupId>
            <artifactId>jooq</artifactId>
            <version>${org.jooq.version}</version>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>

        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-spring-security-adapter</artifactId>
            <version>4.0.0.Final</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>


        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>${org.h2.version}</version>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>${org.postgresql.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-web</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>${spring.security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>${spring.security.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.5.1</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.13</version>
        </dependency>
        <dependency>
            <groupId>commons-httpclient</groupId>
            <artifactId>commons-httpclient</artifactId>
            <version>3.1</version>
        </dependency>
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4.7</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.6.2</version>
        </dependency>
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20090211</version>
        </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.23</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.3.10.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.3.10.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate.common</groupId>
            <artifactId>hibernate-commons-annotations</artifactId>
            <version>4.0.4.Final</version>
        </dependency>
        <dependency>
            <groupId>javax.transaction</groupId>
            <artifactId>jta</artifactId>
            <version>1.1</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.1-api</artifactId>
            <version>1.0.0.Final</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>javax.servlet.jsp.jstl-api</artifactId>
            <version>1.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.web</groupId>
            <artifactId>javax.servlet.jsp.jstl</artifactId>
            <version>1.2.2</version>
        </dependency>
    </dependencies>

Here is my web.xml这是我的web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:spring-root.xml</param-value>
    </context-param>

    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath*:spring-root.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

</web-app>

and spring-root.xmlspring-root.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:security="http://www.springframework.org/schema/security"
       xsi:schemaLocation="http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/security
       http://www.springframework.org/schema/security/spring-security.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

    <mvc:annotation-driven/>

    <context:component-scan base-package="ge.economy.law"/>

    <context:annotation-config/>

    <mvc:resources mapping="/resources/**" location="/resources/"/>

    <bean id="dtSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="org.postgresql.Driver"/>

        <!--LAWYERS.MIA.GE-->
        <property name="url" value="jdbc:postgresql://localhost:5432/lawyers?currentSchema=public"/>
        <!--<property name="url" value="jdbc:postgresql://10.31.16.11:5432/lawyers?currentSchema=public"/>-->
        <property name="username" value="user"/>
        <property name="password" value="pass"/>
    </bean>


    <bean id="propertyPlaceholderConfigurer"
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="ignoreUnresolvablePlaceholders" value="true"/>
        <property name="ignoreResourceNotFound" value="true"/>
    </bean>

    <bean id="transactionAwareDataSource"
          class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
        <constructor-arg ref="dtSource"/>
    </bean>

    <bean class="org.jooq.impl.DataSourceConnectionProvider" name="connectionProvider">
        <constructor-arg ref="transactionAwareDataSource"/>
    </bean>

    <bean id="dsl" class="org.jooq.impl.DefaultDSLContext">
        <constructor-arg ref="config"/>
    </bean>

    <bean class="org.jooq.impl.DefaultConfiguration" name="config">
        <property name="SQLDialect">
            <value type="org.jooq.SQLDialect">POSTGRES</value>
        </property>
        <property name="connectionProvider" ref="connectionProvider"/>
    </bean>

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <bean name="fileService" class="ge.economy.law.service.FileService">
        <!--<property name="rootDir"-->
        <!--value="C:\Program Files\Apache Software Foundation\Apache Tomcat 8.0.27\webapps\ROOT\uploads"/>-->
        <!--<property name="rootDir" value="/usr/share/tomcat/webapps/domains/lawyers-test.economy.ge/uploads"/>-->
        <property name="rootDir" value="/data"/>
    </bean>

    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="500000000"/>
    </bean>

</beans>

Maybe do I have any mistakes in configuration ?也许我在配置上有任何错误?

I`ll leave it here for the future.我会把它留在这里留待未来。 KeyCloackRestTemplate, to get accessToken they are using such a method. KeyCloackRestTemplate,他们使用这样的方法来获取accessToken。 You can find it in org.keycloak.adapters.springsecurity.client->KeycloakClientRequestFactory.class您可以在 org.keycloak.adapters.springsecurity.client->KeycloakClientRequestFactory.class 中找到它

@Controller
@RequestMapping
public class AuthController {

@RequestMapping(value = "/login", method = {RequestMethod.POST})
public String verify(Principal principal,Model model) throws Exception {

    KeycloakAuthenticationToken keycloakAuthenticationToken = (KeycloakAuthenticationToken) principal;
    String token =keycloakAuthenticationToken.getAccount().getKeycloakSecurityContext().getTokenString();

}
 
}

This approach worked for me这种方法对我有用

@GetMapping("/token")
@ResponseBody
public String userinfo(@RegisteredOAuth2AuthorizedClient("${YOUR_CLIENT}") OAuth2AuthorizedClient authorizedClient) {
    return authorizedClient.getAccessToken().getTokenValue();
}

Ref 参考

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 React + Spring Boot:无法从 Header 获取 Authorization 值 - React + Spring Boot: Can't get Authorization value from Header 使用Axios GET发送授权令牌不起作用 - Sending authorization token with Axios GET does not work 如何使用授权码获取访问令牌? - How to get access token using authorization code? Chrome 扩展程序从 header 获取授权令牌 - Chrome extension get authorization token from header 我不明白如何获取令牌。 对React-Native + Redux的授权 - I can not understand how to get token out. Authorization on React-Native + Redux 从标头中获取授权令牌以获取 reactj - Get authorization token from headers into fetch reactj 从Keycloak访问令牌获取客户端会话ID - Get client session id from Keycloak access token Keycloak 自定义身份验证器脚本 - 如何在脚本上下文中获取用户的访问令牌或外部 idp 令牌? - Keycloak custom authenticator script - how to get the access token or external idp token of the user within the script context? 从授权码google oauth2获取刷新令牌 - get refresh token from authorization code google oauth2 如何从 header 授权中的不记名令牌中获取用户 ID - how to get the user id from bearer token in header authorization
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM