javascript
oauth password模式_SpringBoot OAuth2.0 认证授权(密码模式)
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 進行加密
訪問接口 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 认证授权(密码模式)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑连手机热点无法上网怎么办 电脑连手机
- 下一篇: js 只准输入数字_基于TensorFl