首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用OAuth2Login和CustomAuthenticationProvider的Spring-安全性

使用OAuth2Login和CustomAuthenticationProvider的Spring-安全性
EN

Stack Overflow用户
提问于 2022-07-26 11:26:05
回答 1查看 355关注 0票数 -1

在我的例子中,我有一个OAuth2登录名和一个CustomAuthenticationProvider。现在我遇到了一个问题,就是CustomAuthenticationProvider没有被调用,我也不知道为什么。

到目前为止,登录没有问题。

我为客户端注册设置的属性:

代码语言:javascript
运行
复制
# CLIENT FOR AUTHORIZATION CODE GRANT #
spring.security.oauth2.client.registration.login-client.client-id=client-id
spring.security.oauth2.client.registration.login-client.client-secret=secret
spring.security.oauth2.client.registration.login-client.client-authentication-method=client_secret_basic
spring.security.oauth2.client.registration.login-client.scope=openid, profile, roles
spring.security.oauth2.client.registration.login-client.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.login-client.redirect-uri=redirect-uri
spring.security.oauth2.client.provider.login-client.issuer-uri=issuer-uri

我的SecurityConfig:

代码语言:javascript
运行
复制
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
{
    @Value("${keycloak.logout.uri}")
    private String logoutUri;

    @Autowired
    private KeycloakAuthenticationProvider authProvider;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.authenticationProvider(authProvider);
    }

    @Override
    protected void configure(final HttpSecurity http) throws Exception
    {
        // Required for zkoss-uploads
        http.headers()
                .frameOptions()
                .disable();

        // Required for zkoss-logins
        http.csrf().disable();

        // Authorization on request
        http.authorizeRequests()
                .antMatchers("/actuator/**")
                .permitAll()
                .anyRequest()
                .authenticated();

        // OAuth2 Client
        http.oauth2Client();

        // OAuth2 Login
        http.oauth2Login();

        // Logout handling
        http.logout().logoutSuccessUrl(logoutUri);
    }
}

我的CustomAuthenticationProvider:

代码语言:javascript
运行
复制
@Component
public class KeycloakAuthenticationProvider implements AuthenticationProvider
{
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException
    {
        System.out.println("authenticate");
        return authentication;
    }

    @Override
    public boolean supports(Class<?> authentication)
    {
        System.out.println("support");
        return true;
    }
}

注意:我的CustomAuthenticationProvider还没有逻辑,因为我想看看它是否首先被调用。

编辑:

我的依赖关系:

代码语言:javascript
运行
复制
<!-- Security -->
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-oauth2-client</artifactId>
  <version>5.6.1</version>
</dependency>
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-oauth2-jose</artifactId>
  <version>5.6.1</version>
</dependency>
EN

Stack Overflow用户

回答已采纳

发布于 2022-07-28 06:49:51

我现在已经解决了我的问题。问题是,http.oauth2Login()的配置提供了自己的AuthenticationProvider,并且没有被AuthenticationManagerBuilder覆盖。

我的解决方案是向successHandler添加一个oauth2Login。它的任务是重新工作,并设置自动配置创建的现有身份验证。

这是我的代码:

代码语言:javascript
运行
复制
@Autowired
private KeycloakAuthenticationSuccessHandler successHandler;

http.oauth2Login().successHandler(successHandler);

我的successHandler:

代码语言:javascript
运行
复制
@Component
public class KeycloakAuthenticationSuccessHandler implements AuthenticationSuccessHandler
{
    @Value("${logging.groupId}")
    private String location;

    private RequestCache requestCache = new HttpSessionRequestCache();

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
            throws IOException, ServletException
    {
        var persistedAuth = (OAuth2AuthenticationToken) authentication;
        var user = new DefaultOAuth2User(persistedAuth.getAuthorities(), persistedAuth.getPrincipal().getAttributes(), "name");

        /*
         * Sets new OAuth2AuthenticationToken with mapped authorities
         */
        SecurityContextHolder.getContext()
                .setAuthentication(new OAuth2AuthenticationToken(user, mapAuthorities(persistedAuth.getPrincipal().getAttributes()), persistedAuth
                        .getAuthorizedClientRegistrationId()));

        /*
         * Redirecting to the index page of website
         */
        var redirectUri = requestCache.getRequest(request, response).getRedirectUrl();
        redirectStrategy.sendRedirect(request, response, redirectUri);
    }

    @SuppressWarnings("unchecked")
    private Collection<? extends GrantedAuthority> mapAuthorities(Map<String, Object> attributes)
    {
        var resourceRoles = new ArrayList<>();
        var resourceAccess = (Map<String, List<String>>) attributes.get("resource_access");
        if (resourceAccess.containsKey(location))
        {
            resourceRoles.addAll(((Map<String, List<String>>) resourceAccess.get(location)).get("roles"));
        }
        return resourceRoles.isEmpty() ? emptySet() : resourceRoles.stream().map(r -> new SimpleGrantedAuthority(valueOf(r))).collect(toSet());
    }
}

顺便说一句:多亏了马库斯,通过使用调试器的技巧,我找到了解决方案!

票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73122543

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档