当前位置:   article > 正文

springcloud集成Spring Security_springcloud集成springsecurity

springcloud集成springsecurity

1.Spring Security介绍

几乎每个信息系统都需要认证授权保障其可靠性和安全性,当我们用spring框架开发时,Spring Security是一个不错的选择。

Spring Security是一个专注于为Java应用程序提供身份认证和授权功能的强大框架。它基于Spring框架,并提供了全面的安全服务集成,包括认证(Authentication)、授权(Authorization)、攻击防护和会话管理等功能。

2.集成Spring Security

2.1部署认证服务工程

在项目中新建一个springboot工程,并创建controller类定义接口

  1. @Slf4j
  2. @RestController
  3. @RequestMapping("/auth")
  4. public class LoginController {
  5. @RequestMapping("/login-success")
  6. public String loginSuccess() {
  7. return "登录成功";
  8. }
  9. @RequestMapping("/r/r1")
  10. public String r1() {
  11. return "访问r1资源";
  12. }
  13. @RequestMapping("/r/r2")
  14. public String r2() {
  15. return "访问r2资源";
  16. }
  17. }

启动服务,此时我们可以 在浏览器中访问http://localhost:63070/auth/login-successhttp://localhost:63070/auth/r/r1,结果如下

2.2导入Spring Security依赖

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-security</artifactId>
  4. </dependency>

此时再次访问http://localhost:63070/auth/r/r1时,会自动进入/login登录页面,要先登录才能访问/r/r1资源。

/login是spring security提供的,加载可能较慢。

默认用户名user,每次启动服务时密码会自动重新生成并在控制台输出

3自定义用户认证授权测试

1.自定义配置类继承WebSecurityConfigurerAdapter配置类

2.通过重写 configure(HttpSecurity http) 方法来定义安全规则和访问控制。

注意:NoOpPasswordEncoder 通常用于测试或者开发环境中,因为它并不会对密码进行任何加密,而是将密码以明文的形式存储和验证。存在严重的安全风险,因为密码可以很容易地被窃取和滥用。建议不要在生产环境中使用类似的明文密码存储方式。

  1. @EnableWebSecurity
  2. @EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
  3. public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  4. @Bean
  5. public UserDetailsService userDetailsService(){
  6. //这里配置用户信息,这里暂时使用这种方式将用户存储在内存中
  7. InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
  8. manager.createUser(User.withUsername("xiyangyang").password("123").authorities("p1").build());
  9. manager.createUser(User.withUsername("meiyangyang").password("456").authorities("p2").build());
  10. return manager;
  11. }
  12. //获取一个密码编码器对象
  13. @Bean
  14. public PasswordEncoder passwordEncoder(){
  15. //密码为明文方式
  16. return NoOpPasswordEncoder.getInstance();
  17. }
  18. //配置安全拦截机制
  19. @Override
  20. protected void configure(HttpSecurity http) throws Exception{
  21. http.authorizeRequests()
  22. .antMatchers("/r/**").authenticated()//访问/r开始的请求需要认证通过
  23. .anyRequest().permitAll()//其它请求全部放行
  24. .and()
  25. .formLogin().successForwardUrl("/login-success");//登录成功跳转到/login-success
  26. http.logout().logoutUrl("/logout");//退出地址
  27. }
  28. }

此时便可以用自定义的用户名和密码登录访问服务

4.集成OAuth2

4.1OAuth2介绍

4.1.2什么是OAuth2

OAuth 2(Open Authorization 2)是一种授权框架,允许第三方应用程序通过使用授权服务器进行限制的方式,访问受保护的资源,而无需用户将其凭据直接提供给第三方应用程序。它在网络服务之间提供了安全的授权标准。

4.1.3为什么使用OAuth2

OAuth 2.0 是一个开放的标准,被广泛接受和支持。许多大型的互联网服务提供商和平台都实现了 OAuth 2.0,使得开发者可以使用统一的协议和工具来实现授权流程,而无需为每个服务提供商单独开发授权机制。我们熟知的微信扫码就是基于这种OAuth2协议实现的

4.1.4OAuth2的授权模式

Spring Security支持OAuth2认证,OAuth2提供授权码模式、密码模式、简化模式、客户端模式等授权模式,微信扫码登录就是基于授权码模式,其中授权码模式和密码模式应用较多,下面使用Spring Security演示授权码模式、密码模式

4.2导入OAuth2.0依赖

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-oauth2</artifactId>
  4. </dependency>

4.3创建授权服务器配置类

4.3.1获取并配置 AuthenticationManager 的实例

在之前创建的WebSecurityConfig 中注入AuthenticationManager,以支持身份验证功能

  1. public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  2. @Bean
  3. public AuthenticationManager authenticationManagerBean() throws Exception {
  4. return super.authenticationManagerBean();
  5. }
  6. }

 4.3.1创建授权服务器配置类AuthorizationServer

@EnableAuthorizationServer 注解标识并继承AuthorizationServerConfigurerAdapter来配置OAuth2.0 授权服务器

  1. @Configuration
  2. @EnableAuthorizationServer
  3. public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
  4. @Resource(name="authorizationServerTokenServicesCustom")
  5. private AuthorizationServerTokenServices authorizationServerTokenServices;
  6. @Autowired
  7. private AuthenticationManager authenticationManager;
  8. //客户端详情服务
  9. @Override
  10. public void configure(ClientDetailsServiceConfigurer clients)
  11. throws Exception {
  12. clients.inMemory()// 使用in-memory存储
  13. .withClient("baidu")// client_id
  14. .secret("baidu")//客户端密钥
  15. // .secret(new BCryptPasswordEncoder().encode("XcWebApp"))//客户端密钥
  16. .resourceIds("baidu-resource")//资源列表
  17. // 该client允许的授权类型authorization_code,password,refresh_token,implicit,client_credentials
  18. .authorizedGrantTypes("authorization_code", "password","client_credentials","implicit","refresh_token")
  19. .scopes("all")// 允许的授权范围
  20. .autoApprove(false)//false跳转到授权页面
  21. //客户端接收授权码的重定向地址
  22. .redirectUris("http://www.baidu.com")
  23. ;
  24. }
  25. //令牌端点的访问配置
  26. @Override
  27. public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
  28. endpoints
  29. .authenticationManager(authenticationManager)//认证管理器
  30. .tokenServices(authorizationServerTokenServices)//令牌管理服务
  31. .allowedTokenEndpointRequestMethods(HttpMethod.POST);
  32. }
  33. //令牌端点的安全配置
  34. @Override
  35. public void configure(AuthorizationServerSecurityConfigurer security){
  36. security
  37. .tokenKeyAccess("permitAll()") //oauth/token_key是公开
  38. .checkTokenAccess("permitAll()") //oauth/check_token公开
  39. .allowFormAuthenticationForClients() //表单认证(申请令牌)
  40. ;
  41. }
  42. }

 4.2新建令牌配置类

  1. @Configuration
  2. public class TokenConfig {
  3. @Autowired
  4. TokenStore tokenStore;
  5. @Bean
  6. public TokenStore tokenStore() {
  7. //使用内存存储令牌(普通令牌)
  8. return new InMemoryTokenStore();
  9. }
  10. //令牌管理服务
  11. @Bean(name="authorizationServerTokenServicesCustom")
  12. public AuthorizationServerTokenServices tokenService() {
  13. DefaultTokenServices service=new DefaultTokenServices();
  14. service.setSupportRefreshToken(true);//支持刷新令牌
  15. service.setTokenStore(tokenStore);//令牌存储策略
  16. service.setAccessTokenValiditySeconds(7200); // 令牌默认有效期2小时
  17. service.setRefreshTokenValiditySeconds(259200); // 刷新令牌默认有效期3天
  18. return service;
  19. }
  20. }

 4.4授权码模式测试

启动服务,登录成功后在浏览器输入以下地址:

注意:我们在AuthorizationServer已经配置好了以下参数

http://localhost:63070/auth/oauth/authorize?client_id=baidu&response_type=code&scope=all&redirect_uri=http://www.baidu.com

解释: 

client_id:客户端的唯一标识符
response_type:授权码模式固定为code。
scope:客户端权限。
redirect_uri:跳转uri,当授权码申请成功后会跳转到此地址,并在后边带上code参数(授权码)

 此时会出现以下界面选择approve,点击authorize则会跳转到百度页面

我们可以看到地址为https://www.baidu.com/?code=Rd8kGZ,此时便可以拿到授权码Rd8kGZ

注意:授权码只能使用一次。

拿到授权码后,使用postman或者httpclient执行

注意更改code为=Rd8kGZ

POST localhost:63070/auth/oauth/token?client_id=baidu&client_secret=baidu&grant_type=authorization_code&code=Rd8kGZ&redirect_uri=http://www.baidu.com

此时申请令牌成功

解释:

access_token:这是一个访问令牌,用于客户端在访问受保护的资源时进行身份验证和授权。
token_type:指定了访问令牌的类型,这里是 bearer。是OAuth 2.0中定义的一种令牌类型,表示客户端可以使用令牌来访问被授权的资源。
refresh_token:刷新令牌,用于获取新的访问令牌。刷新令牌有更长的有效期,用于在访问令牌过期时获取新的访问令牌。
expires_in:
表示访问令牌的有效期限(秒)。
scope:指定了授权的范围,all 表示这个访问令牌被授予了访问所有资源的权限。

 4.5密码模式测试

密码模式相对授权码模式简单,不需要借助浏览器。

可以直接postman或者httpclient执行

POST localhost:63070/auth/oauth/token?client_id=baidu&client_secret=baidu&grant_type=password&username=xiyangyang&password=123

解释:

client_id=baidu: 这是客户端的唯一标识符。
client_secret=baidu: 客户端的密钥,用于对客户端的身份进行验证。
grant_type=password: 指定了密码授权模式。
username=xiyangyang: 用户名
password=123: 用户密码

执行输出:

注意:密码模式十分简单,但却意味着将用户敏感信息泄露给了client,建议仅在确保安全的环境下使用。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/980430
推荐阅读
相关标签
  

闽ICP备14008679号