关于WebSecurityConfigurerAdapter和ResourceServerConfigurerAdapter区别联系

   1、ResourceServerConfigurerAdapter被配置为不同的端点(参见antMatchers),而WebSecurityConfigurerAdapter不是。

   这两个适配器之间的区别在于,RealServServer配置适配器使用一个特殊的过滤器来检查请求中的承载令牌,以便通过OAuth2对请求进行认证。WebSecurityConfigurerAdapter适配器用于通过会话对用户进行身份验证(如表单登录)

 

2、WebSecurityConfigurerAdapter是默认情况下spring security的http配置,ResourceServerConfigurerAdapter是默认情况下spring security oauth2的http配置 在ResourceServerProperties中,定义了它的order默认值为SecurityProperties.ACCESS_OVERRIDE_ORDER - 1;是大于1的,即WebSecurityConfigurerAdapter的配置的拦截要优先于ResourceServerConfigurerAdapter,优先级高的http配置是可以覆盖优先级低的配置的。

3、某些情况下如果需要ResourceServerConfigurerAdapter的拦截优先于WebSecurityConfigurerAdapter需要在配置文件中添加

security.oauth2.resource.filter-order=99

注意:

@EnableWebSecurity 注解标注的security类创建了一个WebSecurityConfigurerAdapter,且自带了硬编码的order=3,使用spring security而不是auth,即http保护

本项目采用springcloud架构

   gateway用网关服务

 权限系统采用:

关于auth2使用

<dependency>

        <groupId>org.springframework.cloud</groupId>

        <artifactId>spring-cloud-starter-security</artifactId>

</dependency>

<dependency>

         <groupId>org.springframework.cloud</groupId>

         <artifactId>spring-cloud-starter-oauth2</artifactId>

 </dependency>

搭建认证服务:

1. 在启动类加上授权服务加入@EnableAuthorizationServer这个注解,整个项目就是授权服务,然后再构建配置类,放入clientid等信息

继承AuthorizationServerConfigurerAdapter类

  @Override

       public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

              clients.inMemory()

                     .withClient("goodsClient")//客户端id

                     .secret(new BCryptPasswordEncoder().encode("goods123"))//客户端密钥

                     .resourceIds("goodsRes")//客户端资源id

                     .authorizedGrantTypes("authorization_code", "password", "client_credentials", "implicit", "refresh_token")//客户端支持认证格式

                     .scopes("goods")//授权范围标识

                     .autoApprove(false)//是否弹出授权页面 false弹出/true关闭

                     .redirectUris("http://www.baidu.com")//认证成功跳转页面

                     .and()

                     .withClient("resourceClient")

                     .secret(new BCryptPasswordEncoder().encode("resource123"))

                     .resourceIds("resourceRes")

                            .refreshTokenValiditySeconds(10000)

                     .authorizedGrantTypes("authorization_code", "password", "client_credentials", "implicit", "refresh_token")

                     .scopes("resource")

                     .autoApprove(false)

                     .redirectUris("http://www.baidu.com")

                  .and()

                            .withClient("schemeClient")

                            .secret(new BCryptPasswordEncoder().encode("scheme123"))

                            .resourceIds("schemeRes")

                            .refreshTokenValiditySeconds(10000)

                            .authorizedGrantTypes("authorization_code", "password", "client_credentials", "implicit", "refresh_token")

                            .scopes("resource")

                            .autoApprove(false)

                            .redirectUris("http://www.baidu.com");

       }

等配置

2.资源端加入

@EnableResourceServer在启动类的时候,

  

继承ResourceServerConfigurerAdapter类,

       @Override

       public void configure(ResourceServerSecurityConfigurer resources) throws Exception {

              resources.resourceId("resourceRes")

                     .tokenServices(tokenServices())

                     .stateless(true);

       }

然后就可以跑起来了

测试

   http://localhost:9004/oauth/authorize?client_id=resourceClient&response_type=code&redirect_uri=http://www.baidu.com

回车

返回授权码codehttps://www.baidu.com/?code=21F5bK

然后访问resource项目

基于上面的进行token改造

1.生成bean

     @Configuration

        @ConditionalOnProperty(prefix = "type",name="storeType",havingValue = "jwt",matchIfMissing = true)

     public class JwtTokenConfig{

        //将东西放到jwtToken里面

         @Bean

         public TokenStore tokenStore(){

             System.out.println("c*********产生jwt密钥");

             return new JwtTokenStore(jwtAccessTokenConverter());

         }

         //密钥签发令牌

         @Bean

         public JwtAccessTokenConverter jwtAccessTokenConverter(){

            JwtAccessTokenConverter jwtAccessTokenConverter=new JwtAccessTokenConverter();

            jwtAccessTokenConverter.setSigningKey("123456");

            return jwtAccessTokenConverter;

         }

2.将增强器放入AuthorizationServerEndpointsConfigurer endpoints中

TokenEnhancerChain enhancerChain = new TokenEnhancerChain();

              enhancerChain.setTokenEnhancers(Arrays.asList(jwtAccessTokenConverter));

              defaultTokenServices.setTokenEnhancer(enhancerChain);

即可完成。

目标:实现将信息封装在token中,通过增强器

1. @Bean

         @ConditionalOnMissingBean(name="jwtTokenEnhancer")

         public TokenEnhancer jwtTokenEnhancer(){

             System.out.println("c*********jwtTokenEnhancer");

             return  new JwtTokenEnhancer();

         }

2.

public class JwtTokenEnhancer implements TokenEnhancer {

    @Override

    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {

       Map<String,Object> info=new HashMap<String,Object>();

       info.put("company","qi");

        info.put("test","测试");

        ((DefaultOAuth2AccessToken)accessToken).setAdditionalInformation(info);

        return accessToken;

    }

}

3.重新写增强器

              TokenEnhancerChain enhancerChain = new TokenEnhancerChain();           enhancerChain.setTokenEnhancers(Arrays.asList(jwtTokenEnhancer,jwtAccessTokenConverter));

              defaultTokenServices.setTokenEnhancer(enhancerChain);

在资源里面写解析

    @GetMapping("/me1")//对于jwt的请求改变,因为jwt返回的是一个字符串

    public Object getCurrentUser(Authentication user, HttpServletRequest request){

        Object object=SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        //获取头,并且进行剥离

        String header=request.getHeader("Authorization");

       String token= StringUtils.substringAfter(header,"bearer ");

       //对token进行解析,获取额外添加的信息

        try {

            Claims claims = Jwts.parser().setSigningKey("123456".getBytes("UTF-8")).parseClaimsJws(token).getBody();

            String  company=(String)claims.get("company");

            System.out.println("company:"+company);

        }catch(Exception e){

           e.printStackTrace();

        }

        return user;

}

注意token返回的@AuthenticationPrincipal UserDetails user是字符串,所以这个写法要换一下

@GetMapping("/me1")//对于jwt的请求改变,因为jwt返回的是一个字符串

    public Object getCurrentUser(Authentication user, HttpServletRequest request){

        Object object=SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        //获取头,并且进行剥离

        String header=request.getHeader("Authorization");

       String token= StringUtils.substringAfter(header,"bearer ");

       //对token进行解析,获取额外添加的信息

        try {

            Claims claims = Jwts.parser().setSigningKey("123456".getBytes("UTF-8")).parseClaimsJws(token).getBody();

            String  company=(String)claims.get("company");

            System.out.println("company:"+company);

        }catch(Exception e){

           e.printStackTrace();

        }

        return user;

    }

密码模式访问:password

密码请求(post请求)

http://localhost:9004/oauth/token?client_id=resourceClient&client_secret=resource123&grant_type=password&username=peiyajie&password=123456

验证token是否是有效请求(get请求)

http://localhost:9004/oauth/check_token?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsicmVzb3VyY2VSZXMiXSwidGVzdCI6Iua1i-ivlSIsInVzZXJfbmFtZSI6InBlaXlhamllIiwic2NvcGUiOlsicmVzb3VyY2UiXSwiY29tcGFueSI6InFpIiwiZXhwIjoxNTkxNjg3MTIzLCJhdXRob3JpdGllcyI6WyJvcmRlcjo6YWRkIiwib3JkZXI6OnF1ZXJ5Il0sImp0aSI6IjA2NTcwMzFiLTI2NjktNDdkZC05YTZlLWI5NDM5NmM0M2ViMyIsImNsaWVudF9pZCI6InJlc291cmNlQ2xpZW50In0.Y3hIwBjGh-G-hpw1SJDpwWyENFb3P27julkc-A7xRiY

刷新token(post请求)

http://localhost:9004/oauth/token?grant_type=refresh_token&refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsicmVzb3VyY2VSZXMiXSwidGVzdCI6Iua1i-ivlSIsInVzZXJfbmFtZSI6InBlaXlhamllIiwic2NvcGUiOlsicmVzb3VyY2UiXSwiYXRpIjoiMDY1NzAzMWItMjY2OS00N2RkLTlhNmUtYjk0Mzk2YzQzZWIzIiwiY29tcGFueSI6InFpIiwiZXhwIjoxNTkxNjg3NzIzLCJhdXRob3JpdGllcyI6WyJvcmRlcjo6YWRkIiwib3JkZXI6OnF1ZXJ5Il0sImp0aSI6IjBmY2EwNTBiLWEzZTEtNDMzNS1hOTM5LWI0NmFiZTk2ZmQwOCIsImNsaWVudF9pZCI6InJlc291cmNlQ2xpZW50In0.in-S1S0Lt5qjFLOY86mRIIIfX3wExAKTiyeX744dtFQ&client_id=resourceClient&client_secret=resource123

 

 

Spring Boot 2 和 OAuth2 可以通过 Spring Security 实现集成。 下面是一个简单的 Spring Boot 2 OAuth2 集成的示例: 1. 在 pom.xml 文件中添加以下依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.security.oauth.boot</groupId> <artifactId>spring-security-oauth2-autoconfigure</artifactId> <version>2.0.0.RELEASE</version> </dependency> ``` 2. 创建一个 WebSecurityConfigurerAdapter 类并重写 configure 方法: ``` @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/login").permitAll() .antMatchers("/oauth/authorize").authenticated() .and().formLogin().permitAll(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); } } ``` 3. 创建一个 ResourceServerConfigurerAdapter 类并重写 configure 方法: ``` @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/api/**").authenticated() .and().authorizeRequests().anyRequest().permitAll(); } } ``` 4. 创建一个 AuthorizationServerConfigurerAdapter 类并重写 configure 方法: ``` @Configuration @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Autowired private UserDetailsService userDetailsService; @Autowired private DataSource dataSource; @Bean public TokenStore tokenStore() { return new JdbcTokenStore(dataSource); } @Bean public ClientDetailsService clientDetailsService() { return new JdbcClientDetailsService(dataSource); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.jdbc(dataSource); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.tokenStore(tokenStore()).authenticationManager(authenticationManager).userDetailsService(userDetailsService); } } ``` 5. 配置 application.yml 文件: ``` spring: datasource: url: jdbc:mysql://localhost:3306/oauth2 username: root password: root driver-class-name: com.mysql.jdbc.Driver security: oauth2: client: client-id: client client-secret: secret access-token-uri: http://localhost:8080/oauth/token user-authorization-uri: http://localhost:8080/oauth/authorize scope: read,write resource: user-info-uri: http://localhost:8080/api/userinfo ``` 在上面的配置中,我们使用 MySQL 数据库存储 OAuth2 的数据。 6. 创建一个 UserController 类,用于测试: ``` @RestController @RequestMapping("/api") public class UserController { @GetMapping("/userinfo") public Principal user(Principal user) { return user; } } ``` 这个类提供了一个 /api/userinfo 接口,用于返回当前用户的信息。 7. 启动应用程序,并尝试访问 /api/userinfo 接口: ``` http://localhost:8080/api/userinfo ``` 如果没有登录,将重定向到登录页面。登录后,您将获得当前用户的信息。 以上就是一个简单的 Spring Boot 2 OAuth2 集成的示例,可以根据自己的需求进行修改和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值