根据接口api 鉴权 登录获取token
POM
<dependencies>
<!-- 引入JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.6.0</version>
</dependency>
<!-- apache httpclient组件 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<!-- 与数据库操作相关的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- 使用数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.14</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.7.2.RELEASE</version>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.6</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<scope>provided</scope>
</dependency>
<!--引入熔断器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!--<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
</dependencies>
TokenUtils.java
@Component
public class TokenProvider {
//验证JWT是否合法
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token);
return true;
} catch (SignatureException e) {
log.info("Invalid JWT signature.");
log.trace("Invalid JWT signature trace: {}", e);
} catch (MalformedJwtException e) {
log.info("Invalid JWT token.");
log.trace("Invalid JWT token trace: {}", e);
} catch (ExpiredJwtException e) {
log.info("Expired JWT token.");
log.trace("Expired JWT token trace: {}", e);
} catch (UnsupportedJwtException e) {
log.info("Unsupported JWT token.");
log.trace("Unsupported JWT token trace: {}", e);
} catch (IllegalArgumentException e) {
log.info("JWT token compact of handler are invalid.");
log.trace("JWT token compact of handler are invalid trace: {}", e);
}
return false;
}
//创建JWT
public String createToken(String userID, String userName, int refreshTimes) {
long now = (new Date()).getTime();
Date validity = new Date(now + this.expiration);
Map<String, Object> claims = new HashMap<String, Object>();
claims.put(CLAIM_KEY_ISSUER, "EYE-INSIGHT");
claims.put(CLAIM_KEY_ISSUED_AT, System.currentTimeMillis());
claims.put(CLAIM_KEY_SUBJECT, userID);
claims.put(CLAIM_KEY_USER_ID, userID);
claims.put(CLAIM_KEY_USER_NAME, userName);
claims.put(CLAIM_KEY_REFRESH_TIMES, refreshTimes);
return Jwts.builder().signWith(SignatureAlgorithm.HS512, secretKey).setClaims(claims).setExpiration(validity).compact();
}
}
SercurityConfig.java
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SercurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DaoSecurityMetadataSource daoSecurityMetadataSource;
@Autowired
private UrlAccessDecisionManager decisionManager;
//创建jwt认证的Filter Bean
@Bean
public JWTAuthorizeFilter jwtAuthorizeFilterBean() throws Exception {
return new JWTAuthorizeFilter();
}
@Override
public void configure(WebSecurity web) {
String[] split = antMatchers.split(",");
web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers("/health")
.antMatchers("/swagger-ui.html")
.antMatchers("/swagger-resources/**")
.antMatchers("/webjars/springfox-swagger-ui/**/*. {js,css,html}")
.antMatchers(split);
}
@Override
public void configure(HttpSecurity http) throws Exception {
log.info("EnableAuthentication:" + authentication);
http
.csrf().disable()
.headers().frameOptions().disable()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
if (authentication.equals("enable")) {
//对指定的请求进行权限设置
http
// 除上面外的所有请求全部需要鉴权认证
.authorizeRequests()
// 自定义FilterInvocationSecurityMetadataSource
.withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
@Override
public <O extends FilterSecurityInterceptor> O postProcess(O o) {
o.setSecurityMetadataSource(daoSecurityMetadataSource);
o.setAccessDecisionManager(decisionManager);
return o;
}
})
//实现将未认证过的请求,直接返回401,而不返回403
.and()
.exceptionHandling().authenticationEntryPoint(authEntrypoint)
.and()
//在HttpSecurity中增加Filter Bean,必须传入Singletone的bean
.addFilterBefore(jwtAuthorizeFilterBean(), UsernamePasswordAuthenticationFilter.class)
//对于Actuator的Endpoint启动Basic认证
.authorizeRequests()
.antMatchers("/admin/shutdown").authenticated().and().httpBasic();
}
}
}
DaoSecurityMetadataSource.java
@Component
public class DaoSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
@Override
public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
FilterInvocation fi = (FilterInvocation) o;
List<SysRole> neededRoles = this.getRequestNeededRoles(fi.getRequest().getMethod(), fi.getRequestUrl());
if (neededRoles != null) {
return SecurityConfig.createList(neededRoles.stream().map(role -> role.getRolename()
).collect(Collectors.toList()).toArray(new String[]{}));
}
return SecurityConfig.createList("ROLE_LOGIN");
}
}
UrlAccessDecisionManager.java
@Component
public class UrlAccessDecisionManager implements AccessDecisionManager {
/**
* @param auth 用户的权限
* @param o
* @param cas 路径所需要的权限
*/
@Override
public void decide(Authentication auth, Object o, Collection<ConfigAttribute> cas) {
Iterator<ConfigAttribute> iterator = cas.iterator();
while (iterator.hasNext()) {
ConfigAttribute ca = iterator.next();
//当前请求需要的权限
String needRole = ca.getAttribute();
if ("ROLE_LOGIN".equals(needRole)) {
if (auth instanceof AnonymousAuthenticationToken) {
throw new BadCredentialsException("未登录");
} else if (auth instanceof UsernamePasswordAuthenticationToken) {
//登录成功 该url没有绑定权限 默认登录即可访问
return;
} else {
throw new RuntimeException("权限不足!?");
}
}
//当前用户所具有的权限
Collection<? extends GrantedAuthority> authorities = auth.getAuthorities();
for (GrantedAuthority authority : authorities) {
//超级管理员直接跳过
if (authority.getAuthority().equals("ROLE_SUPER_ADMIN")) {
return;
}
if (authority.getAuthority().equals(needRole)) {
return;
}
}
}
throw new AccessDeniedException("权限不足!");
}
@Override
public boolean supports(ConfigAttribute configAttribute) {
return true;
}
@Override
public boolean supports(Class<?> aClass) {
return true;
}
}
详细源码请参考 https://gitee.com/scriptcode/spring-security-token.git
以上源代码直接引入项目即可为项目注入权限控制功能
@MapperScan(basePackages = {"com.xxx.xxx.*", "com.xxx.rbac.*"})//扫描mybatis接口
@SpringBootApplication(scanBasePackages = {"com.xxx.xxx.*", "com.xxx.rbac.*"})
public class EyeInsightApplication {
main()
}