使用手機號密碼進行受權:
使用手機號短信驗證碼進行受權:
經過訪問令牌獲取當前用戶細節:
git
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> </dependency> </dependencies>
@Service public class CustomUserDetailsService { public UserDetails loadUserByPhoneAndPassword(String phone, String password) { if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(password)) { throw new InvalidGrantException("無效的手機號或短信驗證碼"); } // 判斷成功後返回用戶細節 return new User(phone, "", AuthorityUtils.commaSeparatedStringToAuthorityList("admin,user,root")); } public UserDetails loadUserByPhoneAndSmsCode(String phone, String smsCode) { if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(smsCode)) { throw new InvalidGrantException("無效的手機號或短信驗證碼"); } // 判斷成功後返回用戶細節 return new User(phone, "", AuthorityUtils.commaSeparatedStringToAuthorityList("admin,user,root")); } }
public abstract class AbstractCustomTokenGranter extends AbstractTokenGranter { protected AbstractCustomTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType) { super(tokenServices, clientDetailsService, requestFactory, grantType); } @Override protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) { Map<String, String> parameters = new LinkedHashMap(tokenRequest.getRequestParameters()); UserDetails details = getUserDetails(parameters); if (details == null) { throw new InvalidGrantException("沒法獲取用戶信息"); } AuthenticationToken authentication = new AuthenticationToken(details.getAuthorities(),parameters, details); authentication.setAuthenticated(true); authentication.setDetails(details); OAuth2Request storedOAuth2Request = this.getRequestFactory().createOAuth2Request(client, tokenRequest); return new OAuth2Authentication(storedOAuth2Request, authentication); } protected abstract UserDetails getUserDetails(Map<String, String> parameters); }
public class PhonePasswordCustomTokenGranter extends AbstractCustomTokenGranter { private CustomUserDetailsService userDetailsService; public PhonePasswordCustomTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, CustomUserDetailsService userDetailsService) { super(tokenServices, clientDetailsService, requestFactory,"custom_phone_pwd"); this.userDetailsService = userDetailsService; } @Override protected UserDetails getUserDetails(Map<String, String> parameters) { String phone = parameters.get("phone"); String password = parameters.get("password"); parameters.remove("password"); return userDetailsService.loadUserByPhoneAndPassword(phone, password); } }
public class PhoneSmsCustomTokenGranter extends AbstractCustomTokenGranter { private CustomUserDetailsService userDetailsService; public PhoneSmsCustomTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, CustomUserDetailsService userDetailsService) { super(tokenServices, clientDetailsService, requestFactory,"custom_phone_sms"); this.userDetailsService = userDetailsService; } @Override protected UserDetails getUserDetails(Map<String, String> parameters) { String phone = parameters.get("phone"); String smsCode = parameters.get("sms_code"); return userDetailsService.loadUserByPhoneAndSmsCode(phone, smsCode); } }
@Configuration @EnableAuthorizationServer public class AuthorizationServerConfigurer extends AuthorizationServerConfigurerAdapter { @Autowired public CustomUserDetailsService customUserDetailsService; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { //定義一個客戶端支持自定義的受權類型 clients.inMemory() .withClient("demo") .secret(passwordEncoder().encode("demo")) .authorizedGrantTypes("custom_phone_pwd","custom_phone_sms","refresh_token") .scopes("all"); } @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { security.allowFormAuthenticationForClients() .tokenKeyAccess("isAuthenticated()") .checkTokenAccess("permitAll()"); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { List<TokenGranter> tokenGranters = getTokenGranters(endpoints.getTokenServices(), endpoints.getClientDetailsService(), endpoints.getOAuth2RequestFactory()); tokenGranters.add(endpoints.getTokenGranter()); endpoints.tokenGranter(new CompositeTokenGranter(tokenGranters)); } private List<TokenGranter> getTokenGranters(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory) { return new ArrayList<>(Arrays.asList( new PhoneSmsCustomTokenGranter(tokenServices, clientDetailsService, requestFactory, customUserDetailsService), new PhonePasswordCustomTokenGranter(tokenServices, clientDetailsService, requestFactory, customUserDetailsService) )); } }
@Configuration @EnableResourceServer public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .anyRequest() .authenticated(); } }
@RestController public class AuthController { @RequestMapping("/current-info") public Object getUser(Authentication authentication) { return authentication; } }
https://gitee.com/yugu/demo-o...spring
經過繼承AbstractCustomTokenGranter
抽象令牌授予者類實現getUserDetails
方法獲取須要的參數並調用CustomUserDetailsService
用戶細節服務類的方法認證獲取用戶細節數據。服務器