springSecurity双模认证

这里的双模意思是同时支持基于客户端证书和表单登录的认证.大概思路,如果用户提供了客户端证书,优先认证客户端证书,如果认证失败就跳转到基于表单的认证.

1.tomcat或jetty开启客户端认证配置可以看前面的文章.可能要调节客户端认证参数,如tomcat应将clientAuth设为want,
2.配置:

package com.berchina.uums.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.core.env.Environment;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;

import javax.annotation.Resource;
/**
 * Created by on 16/6/16.
 */
@Configuration
public class SecurityConfig {
    @Configuration
    @EnableWebSecurity
    @PropertySource("classpath:config.properties")
    protected static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Resource
        private Environment env;

        @Bean
        public ReloadableResourceBundleMessageSource messageSource() {//本地化(不完全)
            ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
            messageSource.setBasename("classpath:org/springframework/authentication/messages");
            return messageSource;
        }

        @Autowired
        @Qualifier("cerUserDetailsServiceImpl")
        private UserDetailsService cerUserDetailsServiceImpl;
        @Autowired
        @Qualifier("daoUserDetailsServiceImpl")
        private UserDetailsService daoUserDetailsServiceImpl;

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(daoUserDetailsServiceImpl);
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().anyRequest().authenticated()
                    .and().x509().userDetailsService(cerUserDetailsServiceImpl)
                    .and().formLogin().loginPage("/login").permitAll()
                    .and().logout().logoutUrl("/logout").permitAll()
                    .and().exceptionHandling().accessDeniedPage("/exclude/403");
        }

        @Override
        public void configure(WebSecurity web) throws Exception {
            web.ignoring().antMatchers("/static/**", "/exclude/**");
        }

        //暴露AuthenticationManager注册成Bean供@EnableGlobalMethodSecurity使用
        @Bean
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }
    }

    @Configuration
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    protected static class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {

    }
}

上面定义了两个UserDetailsService,就是为了将基于客户端证书和表单登录的认证加载用户分离
3.定义两个UserDetailsService

package com.berchina.uums.service;

import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

/**
 * Created by on 16/6/16.
 */
@Service
public class CerUserDetailsServiceImpl implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        throw new UsernameNotFoundException("没有找到这样的用户");
        //return new User("client","client", AuthorityUtils.createAuthorityList("USER","ADMIN"));
    }
}
package com.berchina.uums.service;

import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

/**
 * Created by on 16/6/16.
 */
@Service
public class DaoUserDetailsServiceImpl implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return new User("client","client", AuthorityUtils.createAuthorityList("USER","ADMIN"));
    }
}

4.测试:
a.https://localhost:8443/testweb/test(包含证书有没有效,即使有效,在数据库能不能找到对应的用户)
b.http://localhost:8080/testweb/test(不是提供证书,只能走表单登录认证)

要思考的问题:
使用证书认证的用户是不需要密码的,如果使用了提供给PreAuthenticatedAuthenticationProvider关于用户信息的一样的UserDetailsService来支持基于表单认证的话,就意味着有潜在的安全风险,因为打算只用证书认证的用户有可能会使用表单登录凭据来认证.有几种方法解决此问题:
a.确保使用证书认证的用户在你的用户存储中,使用合适强度的密码.
b.考虑自定义用户存储来区分那些用户启用了基于表单登录.这可以在用户账号信息表中添加一个字段,并稍为调整下使用JdbcDaoImpl对象的SQL查询来跟踪.
c.为证书登录认证用户配置一个独立的用户详细存储,完全分离那些允许使用基于表单登录的用户.

源码:http://download.csdn.net/detail/xiejx618/9551395

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值