springboot security基于注解配置权限与CAS单点登录配置。
来源:互联网 发布:台湾处境现状 知乎 编辑:程序博客网 时间:2024/06/05 09:55
1.因产品需求方的要求,我经过考察,使用现今流行的springboot框架,security权限配置,刚开始碰到不少坑,后来慢慢琢磨,其实发现也就那么一回事。
2.看本文章前,需要有点springboot对于注解基础,否则可能不太理解。
这个是我的基本配置,有部分大家可能用不到,我就说一下基本使用的哪些。
WebConfig这个类继承WebMvcConfigurerAdapter,其实主要是配置拦截器使用的
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Autowired
private WebDavConfig webDavConfig;
@Autowired
private UserSecurityInterceptor securityInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new BreadCrumbInterceptor()).addPathPatterns("/**");
registry.addInterceptor(new WorkWXInterceptor()).addPathPatterns("/**");
.excludePathPatterns("/login","/logout");//配置登录拦截器拦截路径
// registry.addInterceptor(authInterceptor); //用于跨域时候拦截判断
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT")
.maxAge(3600);
}
@Bean
public FilterRegistrationBean webDavFilterRegistration() {
WebDavEngine engine = new WebDavEngine(webDavConfig.getFsPath());
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(engine.getFilter());
registration.addUrlPatterns(engine.getResourceRoot());
registration.setName("webdav");
registration.setEnabled(webDavConfig.isEnable());
return registration;
}
}
主要其实也就一些拦截器配置使用,其它功能其实很少使用到。具体就那样。
主要的权限配置还是如下:
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
}
这个WebSecurityConfig继承WebSecurityConfigurerAdapter,并重写它的方法来设置安全权限
import mobi.shoumeng.oa.entities.base.config.CasProperties;
/**
* Created by wuyanzhou
* Copyright @2017
*/
import mobi.shoumeng.oa.services.auth.UserAuthService;
import mobi.shoumeng.oa.services.workwx.auth.WorkWXAuthFilter;
import mobi.shoumeng.oa.services.workwx.auth.WorkWXAuthProvider;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserAuthService userAuthService;
@Autowired
private WorkWXAuthProvider workWXAuthProvider;
@Autowired
private MyFilterSecurityInterceptor myFilterSecurityInterceptor;
@Autowired
private CasProperties casProperties; //Cas认证
@Autowired
private UserSecurityInterceptor securityInterceptor;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/weixin","/favicon.ico", "/js/*","/css/*","/jquery-ui-timepicker-addon/*","/images/*", "/fonts/*", "/caldav", "/carddav", "/files/").permitAll()//这些静态可以全部权限访问
.anyRequest().authenticated()
.and()
//增加企业微信登录处理
.addFilterAfter(getWorkWXAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.csrf().disable()
.formLogin().loginPage("/login")//登录页面
.defaultSuccessUrl("/#/notice/index",true)//默认跳转
.permitAll()
.and()
// .rememberMe()
// .tokenValiditySeconds(360000)
// .userDetailsService(userAuthService)
// .useSecureCookie(true)
// .and()
.headers()
.defaultsDisabled()
.contentTypeOptions();
http.sessionManagement() //配置session的功能
.maximumSessions(1)
.maxSessionsPreventsLogin(false) //这个功能很强悍,我这样配置,你的登录会把账号挤出去
.expiredUrl("/login")
.sessionRegistry(sessionRegistry());//session的其他注册配置
http.logout()
.logoutUrl("/logout")
.logoutSuccessUrl(casProperties.getCasServerLogoutUrl()) //这个是登出时候跳到单点服务器上面,把单点注销了账号
.invalidateHttpSession(true) //初始化
.clearAuthentication(true)//清除权限
.invalidateHttpSession(true)
.permitAll();
http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class);
// http.exceptionHandling().accessDeniedPage("/Jurisdiction/insufficientAuthority"); //尝试测试
//session等待时间
// http.sessionManagement().wait(1800);
http.exceptionHandling()
.accessDeniedPage("/Jurisdiction/insufficientAuthority") //当页面没有权限的时候,跳转地方
.authenticationEntryPoint(casAuthenticationEntryPoint()) //单点登录的认证入口
.and()
.addFilter(casAuthenticationFilter()) //记得添加拦截器
.addFilterBefore(casLogoutFilter(), LogoutFilter.class) //添加登出拦截器
.addFilterBefore(singleSignOutFilter(), CasAuthenticationFilter.class);
}
private WorkWXAuthFilter getWorkWXAuthenticationFilter() throws Exception {
WorkWXAuthFilter filter = new WorkWXAuthFilter();//微信登录设置验证
filter.setAuthenticationManager(authenticationManager());
return filter;
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userAuthService)//用户验证
.passwordEncoder(new ShaPasswordEncoder())//加密算法,使用sh1
.and()
.authenticationProvider(workWXAuthProvider);//微信登录的验证入口
auth.authenticationProvider(casAuthenticationProvider()); //单点登录验证
}
// Work around https://jira.spring.io/browse/SEC-2855
@Bean
public SessionRegistry sessionRegistry() {
SessionRegistry sessionRegistry = new SessionRegistryImpl();
return sessionRegistry;
}
@Bean
public static ServletListenerRegistrationBean httpSessionEventPublisher() {
return new ServletListenerRegistrationBean(new HttpSessionEventPublisher());
}
/**认证的入口*/
@Bean
public CasAuthenticationEntryPoint casAuthenticationEntryPoint() {
CasAuthenticationEntryPoint casAuthenticationEntryPoint = new CasAuthenticationEntryPoint();
casAuthenticationEntryPoint.setLoginUrl(casProperties.getCasServerLoginUrl());
casAuthenticationEntryPoint.setServiceProperties(serviceProperties());
return casAuthenticationEntryPoint;
}
/**指定service相关信息*/
@Bean
public ServiceProperties serviceProperties() {
ServiceProperties serviceProperties = new ServiceProperties();
serviceProperties.setService(casProperties.getAppServerUrl() + casProperties.getAppLoginUrl());
serviceProperties.setAuthenticateAllArtifacts(true);
return serviceProperties;
}
/**CAS认证过滤器*/
@Bean
public CasAuthenticationFilter casAuthenticationFilter() throws Exception {
CasAuthenticationFilter casAuthenticationFilter = new CasAuthenticationFilter();
casAuthenticationFilter.setAuthenticationManager(authenticationManager());
casAuthenticationFilter.setFilterProcessesUrl(casProperties.getAppLoginUrl());
return casAuthenticationFilter;
}
/**cas 认证 Provider*/
@Bean
public CasAuthenticationProvider casAuthenticationProvider() {
CasAuthenticationProvider casAuthenticationProvider = new CasAuthenticationProvider();
// casAuthenticationProvider.setAuthenticationUserDetailsService(customUserDetailsService());
casAuthenticationProvider.setUserDetailsService(userAuthService);//这个是我自己配置,根据自己需要配置
//casAuthenticationProvider.setUserDetailsService(customUserDetailsService()); //这里只是接口类型,实现的接口不一样,都可以的。
casAuthenticationProvider.setServiceProperties(serviceProperties());
casAuthenticationProvider.setTicketValidator(cas20ServiceTicketValidator());
casAuthenticationProvider.setKey("casAuthenticationProviderKey");
return casAuthenticationProvider;
}
// @Bean
// public UserDetailsService UserDetailsService(){
// return new UserAuthService();
// }
// /**用户自定义的AuthenticationUserDetailsService*/
// @Bean
// public AuthenticationUserDetailsService<CasAssertionAuthenticationToken> customUserDetailsService(){
// return new UserAuthService();
// }
@Bean
public Cas20ServiceTicketValidator cas20ServiceTicketValidator() { //一种校验方式
return new Cas20ServiceTicketValidator(casProperties.getCasServerUrl());
}
/**单点登出过滤器*/
@Bean
public SingleSignOutFilter singleSignOutFilter() {
SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
singleSignOutFilter.setCasServerUrlPrefix(casProperties.getCasServerUrl());
singleSignOutFilter.setIgnoreInitConfiguration(true);
return singleSignOutFilter;
}
/**请求单点退出过滤器*/
@Bean
public LogoutFilter casLogoutFilter() { //这个地方要注意,service需要你在单点服务器上面配置那边配置跳转,会跳转你需要的页面,否则跳不回来
LogoutFilter logoutFilter = new LogoutFilter(casProperties.getCasServerLogoutUrl()+"?service=" + casProperties.getAppServerUrl() + casProperties.getAppLoginUrl(), new SecurityContextLogoutHandler());
logoutFilter.setFilterProcessesUrl(casProperties.getAppLogoutUrl());
return logoutFilter;
}
}
@Component
public class UserAuthService implements UserDetailsService{//, AuthenticationUserDetailsService<CasAssertionAuthenticationToken> {
@Autowired
private UserRepository userRepository;
@Autowired
DepartementServiceImpl departementServiceImpl;
@Autowired
PepopleServiceImpl pepopleServiceImpl;
@Autowired
CommentSession commentSession;
@Autowired
HttpServletRequest request;
@Autowired
UserRoleServiceImpl userRoleServiceImpl;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
List<GrantedAuthority> grantedAuthorities = new ArrayList <>();
User user = userRepository.findByLoginAccount(s);
if(user.getUseif()!=1){
return null;
}
UserRole userRole = user.getUserRole();
UserRole findByUserRole = userRoleServiceImpl.findByUserRole(userRole.getId());
// System.out.println("测试角色"+userRole.getName());
Set<UserPermission> userPermissions = findByUserRole.getUserPermissions();
for(UserPermission se:userPermissions){
// System.out.println("测试列表"+se.getName());
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(se.getName());
//1:此处将权限信息添加到 GrantedAuthority 对象中,在后面进行全权限验证时会使用GrantedAuthority 对象。
grantedAuthorities.add(grantedAuthority);
}
if (Objects.isNull(user)) {
throw new UsernameNotFoundException(String.format("用户名[%s]未找到", s));
}
org.springframework.security.core.userdetails.User sysuser=new org.springframework.security.core.userdetails.User(user.getUsername(),user.getPassword(),grantedAuthorities);
return sysuser;
}
上面的权限必须用户表必须实现接口User implements UserDetails, Serializable
本人的权限是直接在UserDetails设置,这样避免一些实体类上的问题。权限是根据你的角色里面资源加载,把你的资源URL匹配。
其它的权限验证和网上很多资料差不多,就是配置一下过滤器过滤URL,把每个你配置URL判断是否该资源有没有权限问题等。
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
if(null== configAttributes || configAttributes.size() <=0) {
return;
}
ConfigAttribute c;
String needRole;
for(Iterator<ConfigAttribute> iter = configAttributes.iterator(); iter.hasNext(); ) {
c = iter.next();
needRole = c.getAttribute();
for(GrantedAuthority ga : authentication.getAuthorities()) {//authentication 为在注释1 中循环添加到 GrantedAuthority 对象中的权限信息集合
if(needRole.trim().equals(ga.getAuthority())) {
return;
}
}
}
总体上讲的可能不是很全面,但是基本的配置已经有注解和讲说。可能有部分没有复制上去,不过网上已经很多资料可以查阅,我的方法其实主要配置已经是非常完善。
有什么技术上的问题,也可以加我的QQ询问我。可能平时不在线,也可以留言。。一位开发者的分享。
- springboot security基于注解配置权限与CAS单点登录配置。
- CAS单点登录配置
- CAS单点登录配置
- CAS单点登录配置
- CAS+Spring security实现单点登录之配置篇
- 第四部分:spring security使用cas单点登录配置
- CAS单点登录服务端与客户端配置
- 基于SpringBoot Shiro CAS单点登录实现
- cas 单点登录配置速成
- CAS单点登录配置笔记
- cas单点登录配置速成
- CAS单点登录详细配置
- cas单点登录服务配置
- cas 单点登录,退出配置
- Cas单点登录客户端配置
- 单点登录--CAS服务器配置
- CAS单点登录方案配置
- cas单点登录服务器配置
- CocoaPods 安装与使用及出现的问题
- 对话框中WaitForSingleObject等待线程退出导致程序阻塞的原因及解决
- 深拷贝与浅拷贝
- mysql命令更改列长度
- CSS3-二维变形
- springboot security基于注解配置权限与CAS单点登录配置。
- Redis的持久化
- 对芯片操作的一点总结
- windows上安装tensorflow时报错,“DLL load failed: 找不到指定的模块”的解决方式 最近打算开始研究一下机器学习,今天在windows上装tensorflow花了点功夫
- String 判断字符串是否包含某个字符
- 69. Sqrt(x)
- leach-matlab
- 【Android笔记-异常-7】FrameLayout要嵌套在LinearLayout里否则布局有问题。
- Spark源码解析之SparkSql