Springboot+springsecurity+keycloak統合

5678 ワード

最近チームの各プロジェクトアクセスkeycloakはユーザーのログイン認証を統一的に管理し、認証は各プロジェクトが独立して実現した.
1、keycloakでclientを配置する
keycloak管理インタフェースclientをクリックし、clientを作成し、clientIDを記入する
有効なリダイレクトURI構成は作業指示システムのUIトップページアドレスを指す
暗黙的なフローの有効化
Web起源は*
2、keycloak依存とjsonファイルを加える
pom.xml

4.4.0.Final

    org.keycloak
    keycloak-spring-security-adapter
    ${keycloak.version}


    org.keycloak
    keycloak-spring-boot-starter
    ${keycloak.version}


keycloak.jsonファイルresourcesディレクトリの下に置く
{
  "realm": "realm",
  "auth-server-url": "http://xxx.xxx:8180/auth",
  "ssl-required": "external",
  "resource": "myclient",
  "public-client": true,
  "confidential-port": 0
}

application.propertiesファイル
#keycloak
keycloak.realm=realm
keycloak.resource=myclient
keycloak.auth-server-url=http://xxx.xxx.xxx.xxx:8180/auth
keycloak.ssl-required=external

3、springsecurity+keycloakプロファイルの追加
くだらないことを言わないで、直接コードをつけます
@KeycloakConfiguration
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

    @Autowired
    private SecurityAuthenticationProvider authenticationProvider;

    @Autowired
    private KeycloakAuthenticationProcessingFilter keycloakAuthenticationProcessingFilter;

    @Autowired
    private KeycloakPreAuthActionsFilter keycloakPreAuthActionsFilter;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider);
    }

    @Bean
    public KeycloakConfigResolver keycloakConfigResolver() {
        return new KeycloakSpringBootConfigResolver();
    }

    @Bean
    public FilterRegistrationBean keycloakAuthenticationProcessingFilterRegistrationBean(
            KeycloakAuthenticationProcessingFilter filter) {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
        registrationBean.setEnabled(true);
        return registrationBean;
    }

    @Bean
    public FilterRegistrationBean keycloakPreAuthActionsFilterRegistrationBean(
            KeycloakPreAuthActionsFilter filter) {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
        registrationBean.setEnabled(true);
        return registrationBean;
    }

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().disable()
                .cors().and()
                .sessionManagement().disable()
                .authorizeRequests()
                .anyRequest().permitAll();
        http
                //.addFilterBefore(mySecurityInterceptor, FilterSecurityInterceptor.class)
                .addFilterBefore(keycloakAuthenticationProcessingFilter, FilterSecurityInterceptor.class)
                .addFilterBefore(keycloakPreAuthActionsFilter, KeycloakAuthenticationProcessingFilter.class);
    }

}


4、カスタムAuthenticationProvider
AccessTokenの中のユーザー情報を通じて、本システムの中のそのユーザーの権限情報を照会して、tokenに参加して、具体的な認証方案の各システムはそれぞれ異なって、自分で実現します
@Slf4j
@Component
public class SecurityAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;

    private GrantedAuthoritiesMapper grantedAuthoritiesMapper;

    public void setGrantedAuthoritiesMapper(GrantedAuthoritiesMapper grantedAuthoritiesMapper) {
        this.grantedAuthoritiesMapper = grantedAuthoritiesMapper;
    }

    /**
     *   Authentication,         principal(token)
     */
    @Override
    public Authentication authenticate(Authentication authentication) throws RuntimeException {
        // token       
        KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) authentication;
        AccessToken accessToken = getAccessToken((token));
        String userId = accessToken.getSubject();
        //        ,          
        userService.checkUser(accessToken, userId);
        //  userId         ,  token 
        List grantedAuthorities = roleService.getGrantedAuthorities(userId);
        KeycloakAuthenticationToken authenticationToken = new KeycloakAuthenticationToken(token.getAccount(), token.isInteractive(), mapAuthorities(grantedAuthorities));
        return authenticationToken;
    }

    private AccessToken getAccessToken(KeycloakAuthenticationToken principal) {
        KeycloakAuthenticationToken token = principal;
        KeycloakPrincipal keycloakPrincipal = (KeycloakPrincipal)token.getPrincipal();
        KeycloakSecurityContext context = keycloakPrincipal.getKeycloakSecurityContext();
        return context.getToken();
    }

    private Collection extends GrantedAuthority> mapAuthorities(
            Collection extends GrantedAuthority> authorities) {
        return grantedAuthoritiesMapper != null
                ? grantedAuthoritiesMapper.mapAuthorities(authorities)
                : authorities;
    }

    @Override
    public boolean supports(Class> aClass) {
        return KeycloakAuthenticationToken.class.isAssignableFrom(aClass);
    }

}