parent
b8d0d44e92
commit
41ef7f4b6c
21 changed files with 532 additions and 4 deletions
@ -0,0 +1,109 @@ |
|||||||
|
package com.daqing.financial.hrauth.config; |
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.http.HttpMethod; |
||||||
|
import org.springframework.security.authentication.AuthenticationManager; |
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder; |
||||||
|
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; |
||||||
|
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; |
||||||
|
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; |
||||||
|
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; |
||||||
|
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; |
||||||
|
import org.springframework.security.oauth2.provider.ClientDetailsService; |
||||||
|
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices; |
||||||
|
import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices; |
||||||
|
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; |
||||||
|
import org.springframework.security.oauth2.provider.token.DefaultTokenServices; |
||||||
|
import org.springframework.security.oauth2.provider.token.TokenStore; |
||||||
|
|
||||||
|
/** |
||||||
|
* 配置OAuth2.0授权服务器 |
||||||
|
* |
||||||
|
* @auther River |
||||||
|
* @date 2020/9/21 17:49 |
||||||
|
*/ |
||||||
|
@Configuration |
||||||
|
@EnableAuthorizationServer |
||||||
|
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private TokenStore tokenStore; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private ClientDetailsService clientDetailsService; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private AuthenticationManager authenticationManager; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private AuthorizationCodeServices authorizationCodeServices; |
||||||
|
@Autowired |
||||||
|
public PasswordEncoder passwordEncoder; |
||||||
|
|
||||||
|
/** |
||||||
|
* 配置令牌的安全约束(允许哪些请求访问) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { |
||||||
|
security |
||||||
|
.tokenKeyAccess("permitAll()") // 公开提供公钥加密的端点(就是使用jwt令牌的时候需要的)
|
||||||
|
.checkTokenAccess("permitAll()") // 校验令牌
|
||||||
|
.allowFormAuthenticationForClients(); //允许表单提交,允许客户端访问 OAuth2 授权接口,否则请求 token 会返回 401。
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 配置支持哪些客户端访问 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void configure(ClientDetailsServiceConfigurer clients) throws Exception { |
||||||
|
clients.inMemory() |
||||||
|
.withClient("order-client") |
||||||
|
.secret(passwordEncoder.encode("order-secret-8888")) |
||||||
|
.authorizedGrantTypes("refresh_token", "authorization_code", "password") |
||||||
|
.accessTokenValiditySeconds(3600) |
||||||
|
.scopes("all") |
||||||
|
.and() |
||||||
|
.withClient("user-client") |
||||||
|
.secret(passwordEncoder.encode("user-secret-8888")) |
||||||
|
.authorizedGrantTypes("refresh_token", "authorization_code", "password") |
||||||
|
.accessTokenValiditySeconds(3600) |
||||||
|
.scopes("all"); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 配置令牌(token)的访问端点 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { |
||||||
|
endpoints |
||||||
|
.authenticationManager(authenticationManager) // 密码模式需要
|
||||||
|
.authorizationCodeServices(authorizationCodeServices) // 授权码模式需要
|
||||||
|
.tokenServices(tokenServices()) // 令牌的管理方式
|
||||||
|
.allowedTokenEndpointRequestMethods(HttpMethod.POST); // 允许的请求方式
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 令牌服务 |
||||||
|
*/ |
||||||
|
@Bean |
||||||
|
public AuthorizationServerTokenServices tokenServices(){ |
||||||
|
DefaultTokenServices service = new DefaultTokenServices(); |
||||||
|
service.setClientDetailsService(clientDetailsService); // 客户端信息的服务
|
||||||
|
service.setSupportRefreshToken(true); // 是否产生刷新令牌
|
||||||
|
service.setTokenStore(tokenStore); // 令牌的存储策略
|
||||||
|
service.setAccessTokenValiditySeconds(7200); // 令牌有效期
|
||||||
|
service.setRefreshTokenValiditySeconds(259200); // 刷新令牌有效期
|
||||||
|
return service; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 授权码服务(设置授权码模式的授权码如何存取,暂时在内存,后期在数据库) |
||||||
|
*/ |
||||||
|
@Bean |
||||||
|
public AuthorizationCodeServices authorizationCodeServices(){ |
||||||
|
|
||||||
|
return new InMemoryAuthorizationCodeServices(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,67 @@ |
|||||||
|
package com.daqing.financial.hrauth.config; |
||||||
|
|
||||||
|
import com.daqing.financial.hrauth.service.impl.UserLoginServiceImpl; |
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.security.authentication.AuthenticationManager; |
||||||
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; |
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; |
||||||
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; |
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; |
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder; |
||||||
|
|
||||||
|
/** |
||||||
|
* @auther River |
||||||
|
* @date 2020/9/22 10:26 |
||||||
|
*/ |
||||||
|
@Configuration |
||||||
|
@EnableWebSecurity // 开启security
|
||||||
|
public class SecurityConfig extends WebSecurityConfigurerAdapter { |
||||||
|
|
||||||
|
/** |
||||||
|
* 不能直接new对象,否则会在注入之前被拦截器拦截 |
||||||
|
*/ |
||||||
|
@Bean |
||||||
|
public UserLoginServiceImpl customerLoginService(){ |
||||||
|
|
||||||
|
return new UserLoginServiceImpl(); |
||||||
|
} |
||||||
|
|
||||||
|
// 定义用户信息(查询用户信息),security帮助我们查询,但是需要告诉他如何去查询
|
||||||
|
@Override |
||||||
|
protected void configure(AuthenticationManagerBuilder auth) throws Exception { |
||||||
|
|
||||||
|
auth.userDetailsService(customerLoginService()); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
// 密码编码器,比对密码的方式
|
||||||
|
@Bean |
||||||
|
public PasswordEncoder passwordEncoder(){ |
||||||
|
|
||||||
|
return new BCryptPasswordEncoder(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 认证管理器 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
@Bean |
||||||
|
public AuthenticationManager authenticationManagerBean() throws Exception { |
||||||
|
|
||||||
|
return super.authenticationManagerBean(); |
||||||
|
} |
||||||
|
|
||||||
|
// 安全拦截机制
|
||||||
|
@Override |
||||||
|
protected void configure(HttpSecurity http) throws Exception { |
||||||
|
http.authorizeRequests() |
||||||
|
.antMatchers("/*").authenticated() // 该路径下所有请求都会被拦截
|
||||||
|
.anyRequest().permitAll() // 其余的请求可以通过
|
||||||
|
.and() |
||||||
|
.formLogin() // 允许表单认证
|
||||||
|
.successForwardUrl("/customerLogin/loginSuccess"); // 登录成功跳转路径
|
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,22 @@ |
|||||||
|
package com.daqing.financial.hrauth.config; |
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.security.oauth2.provider.token.TokenStore; |
||||||
|
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; |
||||||
|
|
||||||
|
/** |
||||||
|
* 令牌配置类 |
||||||
|
* |
||||||
|
* @auther River |
||||||
|
* @date 2020/9/22 9:54 |
||||||
|
*/ |
||||||
|
@Configuration |
||||||
|
public class TokenConfig { |
||||||
|
|
||||||
|
@Bean |
||||||
|
public TokenStore tokenStore(){ |
||||||
|
// 内存生成,普通令牌
|
||||||
|
return new InMemoryTokenStore(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
package com.daqing.financial.hrauth.controller; |
||||||
|
|
||||||
|
import com.daqing.financial.hrauth.service.UserLoginService; |
||||||
|
import com.daqing.framework.domain.hrms.request.UserLoginRequest; |
||||||
|
import com.daqing.framework.model.response.ResponseResult; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.web.bind.annotation.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* @auther River |
||||||
|
* @date 2020/9/22 15:27 |
||||||
|
*/ |
||||||
|
@RestController |
||||||
|
@RequestMapping("/hrms/auth/userlogin") |
||||||
|
public class UserLoginController { |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private UserLoginService userLoginService; |
||||||
|
|
||||||
|
@PostMapping("/loginSuccess") |
||||||
|
public String loginSuccess(){ |
||||||
|
|
||||||
|
return "success"; |
||||||
|
} |
||||||
|
|
||||||
|
@GetMapping("/test") |
||||||
|
public String test(){ |
||||||
|
|
||||||
|
return "Hello"; |
||||||
|
} |
||||||
|
|
||||||
|
@PostMapping("/getBackPwd") |
||||||
|
public ResponseResult getBackPwd(@RequestBody UserLoginRequest user){ |
||||||
|
boolean result = userLoginService.getBackPwd(user); |
||||||
|
return result ? ResponseResult.SUCCESS() : ResponseResult.FAIL(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,18 @@ |
|||||||
|
package com.daqing.financial.hrauth.dao; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||||
|
import com.daqing.framework.domain.hrms.UserEntity; |
||||||
|
import org.apache.ibatis.annotations.Mapper; |
||||||
|
import org.apache.ibatis.annotations.Param; |
||||||
|
|
||||||
|
/** |
||||||
|
* @auther River |
||||||
|
* @date 2020/9/22 14:55 |
||||||
|
*/ |
||||||
|
@Mapper |
||||||
|
public interface UserLoginDao extends BaseMapper<UserEntity> { |
||||||
|
|
||||||
|
UserEntity getUser(String code); |
||||||
|
int selectCount(String phoneAccount); |
||||||
|
int updatePasswordByPhoneAccount(@Param("phoneAccount") String phoneAccount, @Param("password") String password); |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
package com.daqing.financial.hrauth.service; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService; |
||||||
|
import com.daqing.framework.domain.hrms.UserEntity; |
||||||
|
import com.daqing.framework.domain.hrms.request.UserLoginRequest; |
||||||
|
|
||||||
|
/** |
||||||
|
* @auther River |
||||||
|
* @date 2020/9/22 15:00 |
||||||
|
*/ |
||||||
|
public interface UserLoginService extends IService<UserEntity> { |
||||||
|
Boolean getBackPwd(UserLoginRequest user); |
||||||
|
} |
@ -0,0 +1,81 @@ |
|||||||
|
package com.daqing.financial.hrauth.service.impl; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
||||||
|
import com.daqing.financial.hrauth.dao.UserLoginDao; |
||||||
|
import com.daqing.financial.hrauth.service.UserLoginService; |
||||||
|
import com.daqing.framework.domain.hrms.UserEntity; |
||||||
|
import com.daqing.framework.domain.hrms.request.UserLoginRequest; |
||||||
|
import com.daqing.framework.domain.hrms.response.HrmsCode; |
||||||
|
import com.daqing.framework.exception.ExceptionCast; |
||||||
|
import org.apache.commons.lang3.StringUtils; |
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority; |
||||||
|
import org.springframework.security.core.userdetails.User; |
||||||
|
import org.springframework.security.core.userdetails.UserDetails; |
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService; |
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException; |
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
|
||||||
|
import javax.annotation.Resource; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.regex.Matcher; |
||||||
|
import java.util.regex.Pattern; |
||||||
|
|
||||||
|
/** |
||||||
|
* @auther River |
||||||
|
* @date 2020/9/22 15:01 |
||||||
|
*/ |
||||||
|
@Service("userLoginService") |
||||||
|
public class UserLoginServiceImpl extends ServiceImpl<UserLoginDao, UserEntity> implements UserLoginService, UserDetailsService { |
||||||
|
|
||||||
|
@Resource |
||||||
|
private UserLoginDao userLoginDao; |
||||||
|
|
||||||
|
@Override |
||||||
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { |
||||||
|
UserEntity user = userLoginDao.getUser(username); |
||||||
|
List<SimpleGrantedAuthority> authorities = new ArrayList<>(); |
||||||
|
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN")); |
||||||
|
System.out.println(user); |
||||||
|
UserDetails userDetails = new User(user.getAccount(),new BCryptPasswordEncoder().encode(user.getPassword()),authorities); |
||||||
|
|
||||||
|
return userDetails; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 忘记密码 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public Boolean getBackPwd(UserLoginRequest user){ |
||||||
|
//判断重置密码参数是否为空
|
||||||
|
if(StringUtils.isEmpty(user.getPhoneAccount())){ |
||||||
|
ExceptionCast.cast(HrmsCode.PHNOE_ACCOUNT_ILLEGAL); |
||||||
|
} |
||||||
|
if(StringUtils.isEmpty(user.getVerifyCode())){ |
||||||
|
ExceptionCast.cast(HrmsCode.VERIFY_CODE_ILLEGAL); |
||||||
|
} |
||||||
|
if(StringUtils.isEmpty(user.getNewPwd())){ |
||||||
|
ExceptionCast.cast(HrmsCode.NEW_PASSWORD_NOT_EMPTY); |
||||||
|
} |
||||||
|
//校验手机账号是否存在
|
||||||
|
int count = this.count(new QueryWrapper<UserEntity>() |
||||||
|
.eq("phone_account", user.getPhoneAccount())); |
||||||
|
if (count == 0) { |
||||||
|
ExceptionCast.cast(HrmsCode.PHNOE_ACCOUNT_ILLEGAL); |
||||||
|
} |
||||||
|
//判断验证码是否匹配
|
||||||
|
|
||||||
|
//密码格式校验
|
||||||
|
Pattern pattern = Pattern.compile("^[a-zA-Z0-9]{8,20}$"); |
||||||
|
Matcher match = pattern.matcher(user.getNewPwd()); |
||||||
|
if(!match.matches()){ |
||||||
|
ExceptionCast.cast(HrmsCode.NEW_PASSWORD_ILLEGAL); |
||||||
|
} |
||||||
|
String newMD5 = new BCryptPasswordEncoder().encode(user.getNewPwd()); |
||||||
|
//根据手机号码修改密码
|
||||||
|
int i = userLoginDao.updatePasswordByPhoneAccount(user.getPhoneAccount(),newMD5); |
||||||
|
return i > 0; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||||
|
|
||||||
|
<mapper namespace="com.daqing.financial.hrauth.dao.UserLoginDao"> |
||||||
|
<update id="updatePasswordByPhoneAccount"> |
||||||
|
update hrms_user set password = #{password} where phone_account = #{phoneAccount} |
||||||
|
</update> |
||||||
|
|
||||||
|
<select id="getUser" parameterType="string" resultType="com.daqing.framework.domain.hrms.UserEntity"> |
||||||
|
SELECT account,password FROM hrms_user WHERE account = #{account} |
||||||
|
</select> |
||||||
|
<select id="selectCount" resultType="java.lang.Integer"> |
||||||
|
select count(1) from hrms_user where phone_account = #{phoneAccount} |
||||||
|
</select> |
||||||
|
|
||||||
|
</mapper> |
@ -0,0 +1,47 @@ |
|||||||
|
package com.daqing.financial.hrms.config; |
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value; |
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; |
||||||
|
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; |
||||||
|
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; |
||||||
|
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; |
||||||
|
import org.springframework.security.oauth2.provider.token.RemoteTokenServices; |
||||||
|
|
||||||
|
@Configuration |
||||||
|
@EnableResourceServer |
||||||
|
@EnableGlobalMethodSecurity(prePostEnabled = true) |
||||||
|
public class ResourceServerConfig extends ResourceServerConfigurerAdapter { |
||||||
|
|
||||||
|
@Value("${security.oauth2.client.client-id}") |
||||||
|
private String clientId; |
||||||
|
|
||||||
|
@Value("${security.oauth2.client.client-secret}") |
||||||
|
private String secret; |
||||||
|
|
||||||
|
@Value("${security.oauth2.authorization.check-token-access}") |
||||||
|
private String checkTokenEndpointUrl; |
||||||
|
|
||||||
|
/* @Autowired |
||||||
|
private RedisConnectionFactory redisConnectionFactory;*/ |
||||||
|
|
||||||
|
/* @Bean |
||||||
|
public TokenStore redisTokenStore (){ |
||||||
|
return new RedisTokenStore(redisConnectionFactory); |
||||||
|
}*/ |
||||||
|
|
||||||
|
@Bean |
||||||
|
public RemoteTokenServices tokenService() { |
||||||
|
RemoteTokenServices tokenService = new RemoteTokenServices(); |
||||||
|
tokenService.setClientId(clientId); |
||||||
|
tokenService.setClientSecret(secret); |
||||||
|
tokenService.setCheckTokenEndpointUrl(checkTokenEndpointUrl); |
||||||
|
return tokenService; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void configure(ResourceServerSecurityConfigurer resources) throws Exception { |
||||||
|
resources.tokenServices(tokenService()); |
||||||
|
} |
||||||
|
} |
Binary file not shown.
@ -0,0 +1,34 @@ |
|||||||
|
package com.daqing.framework.domain.hrms.request; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
/** |
||||||
|
* 登录找回密码请求体对象 |
||||||
|
* |
||||||
|
* @author gongsj |
||||||
|
* @email gongsj@gmail.com |
||||||
|
* @date 2020-09-07 17:12:14 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class UserLoginRequest implements Serializable { |
||||||
|
|
||||||
|
/** |
||||||
|
* 手机账号 |
||||||
|
*/ |
||||||
|
private String phoneAccount; |
||||||
|
/**A |
||||||
|
* 密码 |
||||||
|
*/ |
||||||
|
private String password; |
||||||
|
|
||||||
|
/** |
||||||
|
* 验证码 |
||||||
|
*/ |
||||||
|
private String verifyCode; |
||||||
|
/** |
||||||
|
* 新密码 |
||||||
|
*/ |
||||||
|
private String newPwd; |
||||||
|
} |
Binary file not shown.
Loading…
Reference in new issue