美文网首页
详解spring security 配置多个Authentica

详解spring security 配置多个Authentica

作者: n184 | 来源:发表于2017-11-15 23:56 被阅读0次

    姓名: 李小娜

    [嵌牛导读]:这篇文章主要介绍了详解spring security 配置多个AuthenticationProvider

    [嵌牛鼻子]:spring security的大体介绍   开始配置多AuthenticationProvider  

    [嵌牛提问] :spring security 如何配置多个AuthenticationProvider?

    [嵌牛正文] :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

    packagecom.scau.equipment.config.common.security.provider;

    importorg.springframework.security.authentication.AuthenticationProvider;

    importorg.springframework.security.authentication.UsernamePasswordAuthenticationToken;

    importorg.springframework.security.core.Authentication;

    importorg.springframework.security.core.AuthenticationException;

    importorg.springframework.security.core.GrantedAuthority;

    importorg.springframework.security.core.authority.SimpleGrantedAuthority;

    importorg.springframework.security.core.userdetails.User;

    importorg.springframework.stereotype.Component;

    importjava.util.Arrays;

    importjava.util.List;

    /**

    * Created by Administrator on 2017-05-10.

    */

    @Component

    publicclassInMemoryAuthenticationProviderimplementsAuthenticationProvider {

    privatefinalString adminName ="root";

    privatefinalString adminPassword ="root";

    //根用户拥有全部的权限

    privatefinalList authorities = Arrays.asList(newSimpleGrantedAuthority("CAN_SEARCH"),

    newSimpleGrantedAuthority("CAN_SEARCH"),

    newSimpleGrantedAuthority("CAN_EXPORT"),

    newSimpleGrantedAuthority("CAN_IMPORT"),

    newSimpleGrantedAuthority("CAN_BORROW"),

    newSimpleGrantedAuthority("CAN_RETURN"),

    newSimpleGrantedAuthority("CAN_REPAIR"),

    newSimpleGrantedAuthority("CAN_DISCARD"),

    newSimpleGrantedAuthority("CAN_EMPOWERMENT"),

    newSimpleGrantedAuthority("CAN_BREED"));

    @Override

    publicAuthentication authenticate(Authentication authentication)throwsAuthenticationException {

    if(isMatch(authentication)){

    User user =newUser(authentication.getName(),authentication.getCredentials().toString(),authorities);

    returnnewUsernamePasswordAuthenticationToken(user,authentication.getCredentials(),authorities);

    }

    returnnull;

    }

    @Override

    publicbooleansupports(Class authentication) {

    returntrue;

    }

    privatebooleanisMatch(Authentication authentication){

    if(authentication.getName().equals(adminName)&&authentication.getCredentials().equals(adminPassword))

    returntrue;

    else

    returnfalse;

    }

    }

    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 =newDaoAuthenticationProvider();

    daoAuthenticationProvider.setPasswordEncoder(newBCryptPasswordEncoder());

    daoAuthenticationProvider.setUserDetailsService(userServiceDetails);

    returndaoAuthenticationProvider;

    }

    最后在WebSecurityConfigurerAdapter里配置一个含有以上两个AuthenticationProvider的AuthenticationManager,依然重用spring

    security提供的ProviderManager

    packagecom.scau.equipment.config.common.security;

    importcom.scau.equipment.config.common.security.handler.AjaxLoginFailureHandler;

    importcom.scau.equipment.config.common.security.handler.AjaxLoginSuccessHandler;

    importcom.scau.equipment.config.common.security.provider.InMemoryAuthenticationProvider;

    importorg.springframework.beans.factory.annotation.Autowired;

    importorg.springframework.context.annotation.Bean;

    importorg.springframework.context.annotation.Configuration;

    importorg.springframework.security.authentication.AuthenticationManager;

    importorg.springframework.security.authentication.ProviderManager;

    importorg.springframework.security.authentication.dao.DaoAuthenticationProvider;

    importorg.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;

    importorg.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer;

    importorg.springframework.security.config.annotation.authentication.configurers.provisioning.UserDetailsManagerConfigurer;

    importorg.springframework.security.config.annotation.web.builders.HttpSecurity;

    importorg.springframework.security.config.annotation.web.builders.WebSecurity;

    importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

    importorg.springframework.security.core.GrantedAuthority;

    importorg.springframework.security.core.authority.SimpleGrantedAuthority;

    importorg.springframework.security.core.userdetails.UserDetailsService;

    importorg.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

    importjava.util.Arrays;

    importjava.util.List;

    /**

    * Created by Administrator on 2017/2/17.

    */

    @Configuration

    publicclassSecurityConfigextendsWebSecurityConfigurerAdapter {

    @Autowired

    UserDetailsService userServiceDetails;

    @Autowired

    InMemoryAuthenticationProvider inMemoryAuthenticationProvider;

    @Bean

    DaoAuthenticationProvider daoAuthenticationProvider(){

    DaoAuthenticationProvider daoAuthenticationProvider =newDaoAuthenticationProvider();

    daoAuthenticationProvider.setPasswordEncoder(newBCryptPasswordEncoder());

    daoAuthenticationProvider.setUserDetailsService(userServiceDetails);

    returndaoAuthenticationProvider;

    }

    @Override

    protectedvoidconfigure(HttpSecurity http)throwsException {

    http

    .csrf().disable()

    .rememberMe().alwaysRemember(true).tokenValiditySeconds(86400).and()

    .authorizeRequests()

    .antMatchers("/","/*swagger*/**","/v2/api-docs").permitAll()

    .anyRequest().authenticated().and()

    .formLogin()

    .loginPage("/")

    .loginProcessingUrl("/login")

    .successHandler(newAjaxLoginSuccessHandler())

    .failureHandler(newAjaxLoginFailureHandler()).and()

    .logout().logoutUrl("/logout").logoutSuccessUrl("/");

    }

    @Override

    publicvoidconfigure(WebSecurity web)throwsException {

    web.ignoring().antMatchers("/public/**","/webjars/**","/v2/**","/swagger**");

    }

    @Override

    protectedAuthenticationManager authenticationManager()throwsException {

    ProviderManager authenticationManager =newProviderManager(Arrays.asList(inMemoryAuthenticationProvider,daoAuthenticationProvider()));

    //不擦除认证密码,擦除会导致TokenBasedRememberMeServices因为找不到Credentials再调用UserDetailsService而抛出UsernameNotFoundException

    authenticationManager.setEraseCredentialsAfterAuthentication(false);

    returnauthenticationManager;

    }

    /**

    * 这里需要提供UserDetailsService的原因是RememberMeServices需要用到

    *@return

    */

    @Override

    protectedUserDetailsService userDetailsService() {

    returnuserServiceDetails;

    }

    }

    基本上都是重用了原有的类,很多都是默认使用的,只不过为了修改下行为而重新配置。

    相关文章

      网友评论

          本文标题:详解spring security 配置多个Authentica

          本文链接:https://www.haomeiwen.com/subject/rrskvxtx.html