时间:2021-05-19
前言
发现很少关于spring security的文章,基本都是入门级的,配个UserServiceDetails或者配个路由控制就完事了,而且很多还是xml配置,国内通病...so,本文里的配置都是java配置,不涉及xml配置,事实上我也不会xml配置
spring security的大体介绍
spring security本身如果只是说配置,还是很简单易懂的(我也不知道网上说spring security难,难在哪里),简单不需要特别的功能,一个WebSecurityConfigurerAdapter的实现,然后实现UserServiceDetails就是简单的数据库验证了,这个我就不说了。
spring security大体上是由一堆Filter(所以才能在spring mvc前拦截请求)实现的,Filter有几个,登出Filter(LogoutFilter),用户名密码验证Filter(UsernamePasswordAuthenticationFilter)之类的,Filter再交由其他组件完成细分的功能,例如最常用的UsernamePasswordAuthenticationFilter会持有一个AuthenticationManager引用,AuthenticationManager顾名思义,验证管理器,负责验证的,但AuthenticationManager本身并不做具体的验证工作,AuthenticationManager持有一个AuthenticationProvider集合,AuthenticationProvider才是做验证工作的组件,AuthenticationManager和AuthenticationProvider的工作机制可以大概看一下这两个的java doc,然后成功失败都有相对应该Handler 。大体的spring security的验证工作流程就是这样了。
开始配置多AuthenticationProvider
首先,写一个内存认证的AuthenticationProvider,这里我简单地写一个只有root帐号的AuthenticationProvider
package com.scau.equipment.config.common.security.provider;import org.springframework.security.authentication.AuthenticationProvider;import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;import org.springframework.security.core.Authentication;import org.springframework.security.core.AuthenticationException;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.authority.SimpleGrantedAuthority;import org.springframework.security.core.userdetails.User;import org.springframework.stereotype.Component;import java.util.Arrays;import java.util.List;/** * Created by Administrator on 2017-05-10. */@Componentpublic class InMemoryAuthenticationProvider implements AuthenticationProvider { private final String adminName = "root"; private final String adminPassword = "root"; //根用户拥有全部的权限 private final List<GrantedAuthority> authorities = Arrays.asList(new SimpleGrantedAuthority("CAN_SEARCH"), new SimpleGrantedAuthority("CAN_SEARCH"), new SimpleGrantedAuthority("CAN_EXPORT"), new SimpleGrantedAuthority("CAN_IMPORT"), new SimpleGrantedAuthority("CAN_BORROW"), new SimpleGrantedAuthority("CAN_RETURN"), new SimpleGrantedAuthority("CAN_REPAIR"), new SimpleGrantedAuthority("CAN_DISCARD"), new SimpleGrantedAuthority("CAN_EMPOWERMENT"), new SimpleGrantedAuthority("CAN_BREED")); @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { if(isMatch(authentication)){ User user = new User(authentication.getName(),authentication.getCredentials().toString(),authorities); return new UsernamePasswordAuthenticationToken(user,authentication.getCredentials(),authorities); } return null; } @Override public boolean supports(Class<?> authentication) { return true; } private boolean isMatch(Authentication authentication){ if(authentication.getName().equals(adminName)&&authentication.getCredentials().equals(adminPassword)) return true; else return false; }}support方法检查authentication的类型是不是这个AuthenticationProvider支持的,这里我简单地返回true,就是所有都支持,这里所说的authentication为什么会有多个类型,是因为多个AuthenticationProvider可以返回不同的Authentication。
public Authentication authenticate(Authentication authentication) throws AuthenticationException 方法就是验证过程。
如果AuthenticationProvider返回了null,AuthenticationManager会交给下一个支持authentication类型的AuthenticationProvider处理。
另外需要一个数据库认证的AuthenticationProvider,我们可以直接用spring security提供的DaoAuthenticationProvider,设置一下UserServiceDetails和PasswordEncoder就可以了
@Bean DaoAuthenticationProvider daoAuthenticationProvider(){ DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider(); daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder()); daoAuthenticationProvider.setUserDetailsService(userServiceDetails); return daoAuthenticationProvider; }最后在WebSecurityConfigurerAdapter里配置一个含有以上两个AuthenticationProvider的AuthenticationManager,依然重用spring security提供的ProviderManager
package com.scau.equipment.config.common.security;import com.scau.equipment.config.common.security.handler.AjaxLoginFailureHandler;import com.scau.equipment.config.common.security.handler.AjaxLoginSuccessHandler;import com.scau.equipment.config.common.security.provider.InMemoryAuthenticationProvider;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.authentication.AuthenticationManager;import org.springframework.security.authentication.ProviderManager;import org.springframework.security.authentication.dao.DaoAuthenticationProvider;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer;import org.springframework.security.config.annotation.authentication.configurers.provisioning.UserDetailsManagerConfigurer;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.builders.WebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.authority.SimpleGrantedAuthority;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import java.util.Arrays;import java.util.List;/** * Created by Administrator on 2017/2/17. */@Configurationpublic class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired UserDetailsService userServiceDetails; @Autowired InMemoryAuthenticationProvider inMemoryAuthenticationProvider; @Bean DaoAuthenticationProvider daoAuthenticationProvider(){ DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider(); daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder()); daoAuthenticationProvider.setUserDetailsService(userServiceDetails); return daoAuthenticationProvider; } @Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable() .rememberMe().alwaysRemember(true).tokenValiditySeconds(86400).and() .authorizeRequests() .antMatchers("/","**", "/v2/api-docs").permitAll() .anyRequest().authenticated().and() .formLogin() .loginPage("/") .loginProcessingUrl("/login") .successHandler(new AjaxLoginSuccessHandler()) .failureHandler(new AjaxLoginFailureHandler()).and() .logout().logoutUrl("/logout").logoutSuccessUrl("/"); } @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/public/**", "/webjars/**", "/v2/**", "/swagger**"); } @Override protected AuthenticationManager authenticationManager() throws Exception { ProviderManager authenticationManager = new ProviderManager(Arrays.asList(inMemoryAuthenticationProvider,daoAuthenticationProvider())); //不擦除认证密码,擦除会导致TokenBasedRememberMeServices因为找不到Credentials再调用UserDetailsService而抛出UsernameNotFoundException authenticationManager.setEraseCredentialsAfterAuthentication(false); return authenticationManager; } /** * 这里需要提供UserDetailsService的原因是RememberMeServices需要用到 * @return */ @Override protected UserDetailsService userDetailsService() { return userServiceDetails; }}基本上都是重用了原有的类,很多都是默认使用的,只不过为了修改下行为而重新配置。其实如果偷懒,直接用一个UserDetailsService,在里面做各种认证也是可以的~不过这样就没意思了
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
这里使用的是spring-security和原生的jasigcas包来进行整合,为什么没有直接使用spring提供的spring-security-cas,后面
国际化配置basename中配置的是消息文件的路径在spring-security-core-3.2.0.M1.jar包中的org.springframewor
本文介绍了springboot的maven配置依赖详解,分享给大家,具体如下:我们通过引用spring-boot-starter-parent,添加spring
对于一个大型应用来讲,可能存在多个配置文件。我们可以在启动spring容器时,通过string数组来指定这些配置文件。spring还可以通过将多个配置文件引入到
spring-security里自带了oauth2,正好YIIU里也用到了spring-security做权限部分,那为何不直接集成上第三方登录呢?然后我开始了