一般系统中区分账号角色即可,除了后台管理这类对权限要求比较复杂的。
-
权限表达式:
-
使用
一般在类上或者方法上添加注解使用(不需要对每一个接口配置权限,一般小项目用不到,只要数据库是逻辑删除可恢复这种简单的就可以使用)
在启动类上添加注解:
@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true)
-
配置资源服务器
依赖:<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> </dependency> <dependency> <groupId>io.undertow</groupId> <artifactId>undertow-servlet</artifactId> </dependency> </dependencies>
EnableResourceServer:
package com.cong.security; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; import org.springframework.web.cors.CorsUtils; @Configuration @EnableResourceServer public class MyResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests().antMatchers(HttpMethod.OPTIONS).permitAll();// 放行预请求 http.authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll()// 解决浏览器端预请求直接放过,不作处理 .and().csrf().disable();// 跨站请求访问 } }
JWT配置
package com.cong.security; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 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.JwtAccessTokenConverter; import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; @Configuration public class TokenStoreConfig { /** * prefix---检查的配置项的前缀<br> * name---配置文件中prefix串后面的参数名<br> * havingValue---值对应此配置参数的时候,当前类的所有配置生效<br> * matchIfMissing---设置为true等同于如果配置文件中不设置任何属性,配置文件生效<br> */ @Configuration @ConditionalOnProperty(prefix = "my.security.oAuth2", name = "storeType", havingValue = "jwt", matchIfMissing = true) public static class JwtTokenConfig { /** * 处理token存储 */ @Bean public TokenStore jwtTokenStore() { return new JwtTokenStore(jwtAccessTokenConverter()); } /** * 处理token生成逻辑 */ @Bean public JwtAccessTokenConverter jwtAccessTokenConverter() { JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter(); // 设置签名密钥 accessTokenConverter.setSigningKey("mydev"); return accessTokenConverter; } } }
CORS简单配置:
package com.cong.security; import java.util.Arrays; import java.util.List; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Component; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; @Component @Order(Ordered.HIGHEST_PRECEDENCE) public class MyCorsFilter extends CorsFilter { public MyCorsFilter() { super(configurationSource()); } public static UrlBasedCorsConfigurationSource configurationSource() { CorsConfiguration corsConfig = new CorsConfiguration(); List<String> allowedHeaders = Arrays.asList("Authorization", "Access-Control-Allow-Origin", "Access-Control-Request-Headers", "Access-Control-Request-Method", "x-auth-token", "content-type", "X-Requested-With", "XMLHttpRequest"); List<String> exposedHeaders = Arrays.asList("Authorization", "Access-Control-Allow-Origin", "Access-Control-Request-Headers", "Access-Control-Request-Method", "x-auth-token", "content-type", "X-Requested-With", "XMLHttpRequest"); List<String> allowedMethods = Arrays.asList("POST", "GET", "DELETE", "PUT", "OPTIONS"); corsConfig.setAllowedHeaders(allowedHeaders); corsConfig.setAllowedMethods(allowedMethods); // 配置跨域请求 corsConfig.addExposedHeader(HttpHeaders.SET_COOKIE); corsConfig.setExposedHeaders(exposedHeaders); corsConfig.setMaxAge(36000L); corsConfig.setAllowCredentials(true); corsConfig.addAllowedOrigin("*"); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", corsConfig); return source; } }
将上面三个类提取出来到一个单独的模块中,这样使用JWT无状态登录即可实现模块拆分,方便业务扩展。