SpringBoot 整合 SpringSecurity,token 落地,前后端分离接口安全。

SpringBoot 环境搭建和入门:Spring Boot 2.x 快速入门

导入 mysql 脚本

包含用户表,oauth2.0 数据脚本

https://gitee.com/shizidada/moose-resource/blob/master/moose-security.sql

全部 : https://gitee.com/shizidada/moose/blob/master/src/main/resources/moose.sql

导入依赖

<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.2.5.RELEASE</version>
</dependency>

创建 WebSecurity 配置文件

@Slf4j
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true, securedEnabled = true)
public class MooseWebSecurityConfiguration extends WebSecurityConfigurerAdapter {​@Bean@Overridepublic UserDetailsService userDetailsServiceBean() throws Exception {return new UserDetailsServiceImpl();}
​@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsServiceBean());}
​/*** 用于支持 password 模式 密码模式需要 AuthenticationManager 支持* password 模式一点要加上这个* @throws Exception*/@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}
}

创建 AuthorizationServer 配置

/*** 资源认证配置* <p>* Description:* </p>** @author taohua* @version v1.0.0* @see com.moose.operator.web.security.configure* <p>* [/oauth/authorize] [/oauth/token] [/oauth/check_token]* [/oauth/confirm_access] [/oauth/token_key] [/oauth/error]*/
@Configuration
@EnableAuthorizationServer
public class MooseAuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {​/*** 注入用于支持 password 模式*/@Resourceprivate AuthenticationManager authenticationManager;
​@Resourceprivate AccountService accountService;
​/*** 需要加上,避免循环依赖问题*/@Lazy@Resource(name = "userDetailsServiceBean")private UserDetailsService userDetailsService;
​@Resourceprivate DataSource dataSource;
​@Resourceprivate WebResponseExceptionTranslator customOAuth2ResponseExceptionTranslator;
​/*** 设置用户密码的加密方式*/@Beanpublic BCryptPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}
​/*** Token 持久化** @return TokenStore*/@Beanpublic TokenStore tokenStore() {// 基于 JDBC 实现,令牌保存到数据库return new JdbcTokenStore(dataSource);}
​/*** A service that provides the details about an OAuth2 client.** @return ClientDetailsService* <p>* 基于 JDBC 实现,需要事先在数据库配置客户端信息*/@Beanpublic ClientDetailsService jdbcClientDetailsService() {return new JdbcClientDetailsService(dataSource);}
​/*** Authorization Server endpoints.** @throws Exception*/@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.tokenStore(tokenStore()).exceptionTranslator(customOAuth2ResponseExceptionTranslator);
​// 用于支持密码模式endpoints.authenticationManager(authenticationManager);}
​/*** 授权服务安全配置** @throws Exception*/@Overridepublic void configure(AuthorizationServerSecurityConfigurer oauthServer)throws Exception {oauthServer.passwordEncoder(passwordEncoder());
​/*** 对于端点可以匿名访问* [/oauth/authorize] [/oauth/token] [/oauth/check_token]* [/oauth/confirm_access] [/oauth/token_key] [/oauth/error]*/oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("permitAll()").allowFormAuthenticationForClients();}
​/*** 授权客户端配置** @throws Exception*/@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {// 客户端配置clients.withClientDetails(jdbcClientDetailsService());}
}

创建 ResourceServer配置

@Configuration
@EnableResourceServer
public class MooseResourceServerConfiguration extends ResourceServerConfigurerAdapter {​/*** 保存匿名访问的 url,表示可以不需要权限直接可以访问*/private final List<String> anonymousAntPatterns = new ArrayList<>();
​@Resourceprivate MooseAuthenticationFailureHandler mooseAuthenticationFailureHandler;
​@Resourceprivate MooseAccessDeniedHandler mooseAccessDeniedHandler;
​@Resourceprivate MooseAuthenticationEntryPoint mooseAuthenticationEntryPoint;
​/*** 需要加上,避免循环依赖问题*/@Lazy@Resourceprivate TokenStore tokenStore;
​@Overridepublic void configure(HttpSecurity http) throws Exception {​http.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll();
​// 对登录注册要允许匿名访问for (String pattern : anonymousAntPatterns) {http.authorizeRequests().antMatchers(pattern).permitAll();}
​// 禁用 sessionhttp.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests().anyRequest().authenticated().and().cors().and().csrf().disable();}
​@Overridepublic void configure(ResourceServerSecurityConfigurer resources) throws Exception {// 配置资源 ID,需要在 oauth_client_details 表中添加,详细查看数据库脚本resources.resourceId("app-resources").stateless(true);resources.accessDeniedHandler(mooseAccessDeniedHandler);resources.authenticationEntryPoint(mooseAuthenticationEntryPoint);}
}

自定义认证 UserDetailsService

  • 需要继承 UserDetailsService 类
  • 重写 loadUserByUsername 方法,通过这个方法得到访问接口传递的用户名
  • 根据用户名进行用户名密码校验和权限校验
  • 查询出来的用户信息构建 UserDetails 对应进行返回传递

具体可以查看 https://gitee.com/shizidada/moose/blob/master/src/main/java/com/moose/operator/web/service/impl/UserDetailsServiceImpl.java

public class UserDetailsServiceImpl implements UserDetailsService {​@Resourceprivate AccountServiceImpl accountService;
​@Resourceprivate PasswordServiceImpl passwordService;
​/*** Spring Security** @param accountName 账号* @return 是否成功* @throws UsernameNotFoundException 用户名密码异常*/@Overridepublic UserDetails loadUserByUsername(String accountName)throws UsernameNotFoundException {​if (StringUtils.isEmpty(accountName)) {throw new BusinessException(ResultCode.ACCOUNT_IS_EMPTY);}
​AccountDTO accountDTO = accountService.getByAccountName(accountName);if (ObjectUtils.isEmpty(accountDTO)) {throw new BusinessException(ResultCode.ACCOUNT_OR_PASSWORD_ERROR);}
​// TODO: 禁用账号如何防止多次请求,访问数据库 ???
​PasswordDTO passwordDTO = passwordService.getByAccountId(accountDTO.getAccountId());if (ObjectUtils.isEmpty(passwordDTO)) {throw new BusinessException(ResultCode.ACCOUNT_OR_PASSWORD_ERROR);}
​// TODO: 角色、权限集合List<GrantedAuthority> grantedAuthorities = new ArrayList();grantedAuthorities.add(new SimpleGrantedAuthority("USER"));return new MooseUserDetails(accountDTO, passwordDTO, grantedAuthorities);}
}

自定义验证,需要用到 Bean

  • MooseUserDetails 构建用户和权限信息

    • https://gitee.com/shizidada/moose/blob/master/src/main/java/com/moose/operator/web/security/component/MooseUserDetails.java
  • MooseAccessDeniedHandler 用来解决认证过的用户访问无权限资源时的异常

    • https://gitee.com/shizidada/moose/blob/master/src/main/java/com/moose/operator/web/security/component/MooseAccessDeniedHandler.java
  • MooseAuthenticationEntryPoint 用来解决匿名用户访问无权限资源时的异常

    • https://gitee.com/shizidada/moose/blob/master/src/main/java/com/moose/operator/web/security/component/MooseAuthenticationEntryPoint.java
  • MooseAuthenticationExceptionSerializer 自定义授权错误解析器

    • https://gitee.com/shizidada/moose/blob/master/src/main/java/com/moose/operator/web/security/component/MooseAuthenticationExceptionSerializer.java
  • MooseAuthenticationFailureHandler 自定义授权失败或错误

    • https://gitee.com/shizidada/moose/blob/master/src/main/java/com/moose/operator/web/security/component/MooseAuthenticationFailureHandler.java
  • MooseAuthenticationResponseExceptionTranslator 自定义授权错误传输器

    • https://gitee.com/shizidada/moose/blob/master/src/main/java/com/moose/operator/web/security/component/MooseAuthenticationResponseExceptionTranslator.java

测试

  • 向 oauth_client_details 表中 authorized_grant_types 字段添加 password 模式
  • 向数据库添加测试用户, password 需要用 BCryptPasswordEncoder 进行加密
# t_account 表
insert  into `t_account`(`account_id`,`account_name`,`status`,`phone`,`create_time`,`update_time`) values ('785919644115668992','江景','1','1537031501','2020-12-08 17:24:04','2020-12-08 17:24:04');
​
# t_password 表
insert  into `t_password`(`password_id`,`account_id`,`password`,`create_time`,`update_time`) values ('785919644115668993','785919644115668992','$2a$10$Ll17vDGG3DoABuy9L026KeqjAasYknMXR3cHmxiTyfDl9dS8RtGbi','2020-12-08 17:24:04','2020-12-08 17:24:04');

访问接口 localhost:7000/api/v1/user/info

登录错误返回,随便输入用户名

获取 access_token

localhost:7000/oauth/token?username=江景&password=123456&grant_type=password&client_id=client&client_secret=secret

携带 access_token 访问

localhost:7000/api/v1/user/info?access_token=15890e98-cda9-4ce4-9b65-1aa66821c3f5

如果对您有帮助可以给作者一个赞 !

代码地址: https://gitee.com/shizidada/moose

oauth password模式_SpringBoot OAuth2.0 认证授权(密码模式)相关推荐

  1. Oauth2.0认证---授权码模式

    目录: 1.功能描述 2.客户端的授权模式 3.授权模式认证流程 4.代码实现 1.功能描述 OAuth在"客户端"与"服务提供商"之间,设置了一个授权层(au ...

  2. Spring Security OAuth2.0认证授权知识概括

    Spring Security OAuth2.0认证授权知识概括 安全框架基本概念 基于Session的认证方式 Spring Security简介 SpringSecurity详解 分布式系统认证方 ...

  3. Spring Security OAuth2.0认证授权五:用户信息扩展到jwt

    历史文章 [Spring Security OAuth2.0认证授权一:框架搭建和认证测试] [Spring Security OAuth2.0认证授权二:搭建资源服务] [Spring Securi ...

  4. Spring Security OAuth2.0认证授权三:使用JWT令牌

    历史文章 [Spring Security OAuth2.0认证授权一:框架搭建和认证测试] [Spring Security OAuth2.0认证授权二:搭建资源服务] 前面两篇文章详细讲解了如何基 ...

  5. Spring Security OAuth2.0认证授权

    文章目录 1.基本概念 1.1.什么是认证 1.2 什么是会话 1.3什么是授权 1.4授权的数据模型 1.4 RBAC 1.4.1 基于角色的访问控制 2.基于Session的认证方式 3.整合案例 ...

  6. SpringSecurity OAuth2.0认证授权-part2

    此篇文章包含oauth2项目搭建.整合jwt.授权方式测试: 篇幅过长,拆分为: part1: 认证授权原理回顾及分布式系统认证方案: part2: oauth2项目搭建.授权方式测试: part3: ...

  7. OAuth2.0_授权服务配置_密码模式及其他模式_Spring Security OAuth2.0认证授权---springcloud工作笔记145

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 然后我们再去看看密码模式和其他的模式来获取令牌. 我们要知道授权码模式是最安全的一种方式.对吧.验 ...

  8. OAuth2.0_授权服务配置_授权码模式_Spring Security OAuth2.0认证授权---springcloud工作笔记144

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 前面咱们已经配置好了授权服务器, 包括客户端信息, 包括申请令牌和授权码的接口配置 包括对接口安全 ...

  9. 使用Owin中间件搭建OAuth2.0认证授权服务器

    前言 这里主要总结下本人最近半个月关于搭建OAuth2.0服务器工作的经验.至于为何需要OAuth2.0.为何是Owin.什么是Owin等问题,不再赘述.我假定读者是使用Asp.Net,并需要搭建OA ...

最新文章

  1. 看我是如何利用升级系统一键GetShell
  2. jQuery 在Table中选择input之类的东西注意事项
  3. python运行非常慢的解决-python执行太慢
  4. 浏览器根据什么来判定脚本失控?
  5. Objective C 基础教程
  6. 泊松分布的分布函数_10分钟了解泊松分布
  7. tomcat(13)Host和Engine容器
  8. 怎么才能成为一名PHP专家?
  9. eyb:Java代码通过FastDFS实现文件上传
  10. Genotype陨石的秘密
  11. 2022年全球及中国MICC电缆行业运行战略规划与未来投资策略分析报告
  12. java判断今天是否是节假日_java 判断日期是否是节假日
  13. 计算机sci多少字,一篇英文sci论文多少字
  14. Scheme 编程语言(1)介绍
  15. 登录mysql报错Failed to connect to backoff 或 Failed to get D-Bus connection: Operation not permitted解决方法
  16. Python: 第三方模块(modules)的安装位置 (2014-08-24 23:19:18)转载▼ 标签: site-packages dist-packages 默认安装目录 分类: Pyth
  17. 【软件工具】Anaconda使用总结
  18. MACD与OBV结合,用OBV进行改进MACD指标公式
  19. 【HTML】HTML网页设计----模仿汉服前端设计
  20. 学生成绩管理系统mysql课程设计_学生成绩管理系统数据库课程设计报告.doc

热门文章

  1. python编写成绩及格不及格_python小练习:读入一个考试得分,判断这个分数是哪个等级,并输出,考虑异常场景...
  2. 2019_7_31python
  3. MATLAB实现多元线性回归预测
  4. 【CodeVS】1083 Cantor表
  5. The podfile
  6. Javascript实现的2048
  7. linux日常管理-防火墙selinux
  8. 程序员买房与程序员转型
  9. 理解图像傅里叶变换的频谱图
  10. MFC绘制动态曲线,用双缓冲绘图技术防闪烁