`@EnableOAuth2Sso`注解详情

@EnableOAuth2Sso注解详情

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@EnableOAuth2Client
@EnableConfigurationProperties({OAuth2SsoProperties.class}) // [1]
@Import({OAuth2SsoDefaultConfiguration.class, OAuth2SsoCustomConfiguration.class, ResourceServerTokenServicesConfiguration.class})
public @interface EnableOAuth2Sso {
}

由源码知@EnableOAuth2Sso是一个组合注解。

@EnableOAuth2Client

@EnableOAuth2Client通过@Import导入了OAuth2ClientConfiguration类。

OAuth2ClientConfiguration类中注入了3个Bean:OAuth2ClientContextFilterAccessTokenRequestOAuth2ClientContextConfiguration

OAuth2ClientContextFilter加入到过滤器链中,当后续的认证抛出UserRedirectRequiredException异常时,会重定向。。。「后续补充」

@EnableConfigurationProperties

@EnableConfigurationProperties启用OAuth2SsoProperties配置类。

security.oauth2.sso.loginPath=/login

@Import

导入了OAuth2SsoDefaultConfigurationOAuth2SsoCustomConfigurationResourceServerTokenServicesConfiguration三个配置类。

看OAuth2SsoDefaultConfiguration的条件@Conditional({OAuth2SsoDefaultConfiguration.NeedsWebSecurityCondition.class})和OAuth2SsoCustomConfiguration上的条件@Conditional({EnableOAuth2SsoCondition.class}),它们两个是取反的逻辑,即只能有一个生效。

@Conditional({EnableOAuth2SsoCondition.class})是指当项目中有WebSecurityConfigurerAdapter.class的Bean时为真,即项目中继承了WebSecurityConfigurerAdapter抽象类。

  1. OAuth2SsoDefaultConfiguration配置类

OAuth2SsoDefaultConfiguration继承了WebSecurityConfigurerAdapter,重写了config(HttpSecurity)方法

OAuth2SsoDefaultConfiguration#configure

protected void configure(HttpSecurity http) throws Exception {
    ((AuthorizedUrl)http.antMatcher("/**").authorizeRequests().anyRequest()).authenticated();
    (new SsoSecurityConfigurer(this.applicationContext)).configure(http);
}

方法中配置了所有的请求都需要认证后访问。另外,调用了SsoSecurityConfigurer的config方法。

SsoSecurityConfigurer#configure

public void configure(HttpSecurity http) throws Exception {
  // 在[1]处已经启用了OAuth2SsoProperties属性类
    OAuth2SsoProperties sso = (OAuth2SsoProperties)this.applicationContext.getBean(OAuth2SsoProperties.class);
  // oauth2SsoFilter方法返回OAuth2ClientAuthenticationProcessingFilter对象
  // OAuth2ClientAuthenticationConfigurer主要作用将OAuth2ClientAuthenticationProcessingFilter添加到过滤器链中
    http.apply(new SsoSecurityConfigurer.OAuth2ClientAuthenticationConfigurer(this.oauth2SsoFilter(sso)));
  // 认证失败的异常处理端点
    this.addAuthenticationEntryPoint(http, sso);
}

SsoSecurityConfigurer#oauth2SsoFilter

private OAuth2ClientAuthenticationProcessingFilter oauth2SsoFilter(OAuth2SsoProperties sso) {
    OAuth2RestOperations restTemplate = ((UserInfoRestTemplateFactory)this.applicationContext.getBean(UserInfoRestTemplateFactory.class)).getUserInfoRestTemplate();
    ResourceServerTokenServices tokenServices = (ResourceServerTokenServices)this.applicationContext.getBean(ResourceServerTokenServices.class);
    OAuth2ClientAuthenticationProcessingFilter filter = new OAuth2ClientAuthenticationProcessingFilter(sso.getLoginPath());
    filter.setRestTemplate(restTemplate);
    filter.setTokenServices(tokenServices);
    filter.setApplicationEventPublisher(this.applicationContext);
    return filter;
}

方法返回OAuth2ClientAuthenticationProcessingFilter对象,OAuth2ClientAuthenticationProcessingFilter与UsernamePasswordAuthenticationFilter一样处理用户认证的逻辑。不同的是UsernamePasswordAuthenticationFilter通过username和password去认证了,而OAuth2ClientAuthenticationProcessingFilter是通过OAuth2RestOperations「restTemplate」取获取accessToken,然后使用accessToken获取认证信息。

SsoSecurityConfigurer.OAuth2ClientAuthenticationConfigurer类

private static class OAuth2ClientAuthenticationConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
    private OAuth2ClientAuthenticationProcessingFilter filter;

    OAuth2ClientAuthenticationConfigurer(OAuth2ClientAuthenticationProcessingFilter filter) {
        this.filter = filter;
    }

    public void configure(HttpSecurity builder) throws Exception {
        OAuth2ClientAuthenticationProcessingFilter ssoFilter = this.filter;
        ssoFilter.setSessionAuthenticationStrategy((SessionAuthenticationStrategy)builder.getSharedObject(SessionAuthenticationStrategy.class));
      // 将OAuth2ClientAuthenticationProcessingFilter添加到过滤器链中
        builder.addFilterAfter(ssoFilter, AbstractPreAuthenticatedProcessingFilter.class);
    }
}

该类的config方法中为OAuth2ClientAuthenticationProcessingFilter设置了Session策略,然后将其添加到过滤器链中。

  1. OAuth2SsoCustomConfiguration配置类

该类OAuth2SsoCustomConfiguration作用是:如果项目中实现了WebSecurityConfigurerAdapter的配置类,则为该类使用代理。

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if (this.configType.isAssignableFrom(bean.getClass()) && bean instanceof WebSecurityConfigurerAdapter) {
      // 使用代理
        ProxyFactory factory = new ProxyFactory();
        factory.setTarget(bean);
        factory.addAdvice(new OAuth2SsoCustomConfiguration.SsoSecurityAdapter(this.applicationContext));
        bean = factory.getProxy();
    }

    return bean;
}

SsoSecurityAdapter

private static class SsoSecurityAdapter implements MethodInterceptor {
    private SsoSecurityConfigurer configurer;

    SsoSecurityAdapter(ApplicationContext applicationContext) {
        this.configurer = new SsoSecurityConfigurer(applicationContext);
    }

    public Object invoke(MethodInvocation invocation) throws Throwable {
        if (invocation.getMethod().getName().equals("init")) {
        // 在调用init方法添加SsoSecurityConfigurer配置类
            Method method = ReflectionUtils.findMethod(WebSecurityConfigurerAdapter.class, "getHttp");
            ReflectionUtils.makeAccessible(method);
            HttpSecurity http = (HttpSecurity)ReflectionUtils.invokeMethod(method, invocation.getThis());
            this.configurer.configure(http);
        }

        return invocation.proceed();
    }
}
  1. ResourceServerTokenServicesConfiguration

这个配置类主要是向容器中添加了UserInfoRestTemplateFactory和JwtToken相关的配置,被用于获取用户信息及token的生成与存储。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,关于你的问题,我可以给你一些指导。 Spring Boot 能够轻松集成 OAuth2,实现单点登录(SSO)功能。OAuth2 是一种授权协议,允许用户在不泄露密码的情况下授权第三方应用访问他们的资源。以下是基本步骤: 1. 添加依赖项 在 pom.xml 文件中添加以下依赖项: ``` <dependency> <groupId>org.springframework.security.oauth.boot</groupId> <artifactId>spring-security-oauth2-autoconfigure</artifactId> <version>2.1.0.RELEASE</version> </dependency> ``` 2. 配置 Spring Security 在 Spring Security 配置文件中添加以下代码: ``` @Configuration @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("client-id") .secret("client-secret") .authorizedGrantTypes("authorization_code") .scopes("read", "write") .redirectUris("http://localhost:8080/login") .and() .withClient("client-id-2") .secret("client-secret-2") .authorizedGrantTypes("password") .scopes("read", "write") .accessTokenValiditySeconds(3600) .and() .withClient("client-id-3") .secret("client-secret-3") .authorizedGrantTypes("client_credentials") .scopes("read", "write"); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authenticationManager(authenticationManager); } } ``` 3. 配置资源服务器 在资源服务器配置文件中添加以下代码: ``` @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/api/**").authenticated() .anyRequest().permitAll(); } } ``` 4. 集成 Spring Boot 在 Spring Boot 启动类上添加注解 @EnableOAuth2Sso,示例如下: ``` @SpringBootApplication @EnableOAuth2Sso public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 以上就是基本的步骤,具体实现可以参考 Spring 官方文档和示例代码。希望可以帮助到你。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超人@不会飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值