spring security 整合sso全记录

介绍一下我司的sso流程

我司的sso流程:

  1. app在sso系统注册想被sso拦截的sso url, 本app注册了app/index
  2. sso会在公司网关层拦截 app/index的url,根据用户cookie是否携带正确token,决定是否触发登录流程(如果已经登录,则直接放行到(app/index),如果没有登录,则转发到全司统一的sso登录页面)
  3. sso验证通过后,会重定向到app(app/index),app可以拿到用户登录信息

app security 整合sso的思路

  1. app对用户提交的请求路径,利用spring security 判断用户是否登录,如未登录,则重定向到app/index, sso会在网关层抓到这个url,从而触发sso登录流程.
  2. 登录成功后,app拿到登录信息(userid等),设置认证通过,获取user在本app的角色等信息,并保存到security.
  3. 登录成功后的用户,再次访问app时,app就可以利用spring security判断用户是否登录了.

要解决的问题

  1. 可以看出,本案例中其实不需要spring security默认提供的登录页面,我们要让security知道我们想要跳转的登录url是app/index(POST方法)
  2. sso登录成功后,会跳转回到我们的app url(app/index,GET方法).怎么让security知道,并启动spring security的认证流程?
  3. 重写security的验证方法attemptAuthentication, 我们认为通过sso登录成功后,就默认登录app是验证通过的.
  4. 由于app是采用的前台loadbalance+后台机器集群的方式.前台的loadballance方式,由于我司流程,不能设置sticky session. 所以需采用springsession(redis)的方式

上代码

  1. 解决第一个问题,很简单,在spring-security.xml里面配置
<security:form-login login-page="/app/index"/>
  1. 第二个问题的解决稍微复杂一点:
    我们要重写验证流程,是显而易见的.于是,新建cMToolAuthenticationFilter extends UsernamePasswordAuthenticationFilter
    xml配置如下
<security:http auto-config="true" use-expressions="true">
......
	<security:custom-filter ref="cMToolAuthenticationFilter" before="FORM_LOGIN_FILTER"/>
</security:http>


 <security:authentication-manager alias="authenticationManager">
	  <security:authentication-provider ref="cMToolAuthenticationProvider"/>
</security:authentication-manager>

<bean id="cMToolAuthenticationProvider" class="com.app.provider.CMToolAuthenticationProvider"/>
 
<bean id="cMToolAuthenticationFilter" class="com.app.filter.CMToolAuthenticationFilter">
        <property name="authenticationManager" ref="authenticationManager"/>
</bean>

在CMToolAuthenticationFilter里面,增加initCMAuFilter方法,指定触发security验证流程的url:/app/index

public class CMToolAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    @PostConstruct
    public void initCMAuFilter(){
    	//这里指定触发security验证流程的url:/app/index
        RequestMatcher requiresAuthenticationRequestMatcher = new AntPathRequestMatcher("/app/index", "GET");
        this.setRequiresAuthenticationRequestMatcher(requiresAuthenticationRequestMatcher);
        //这里可以顺便指定一下,登录成功后的自定义handler=>CMToolSuccessHandler
        this.setAuthenticationSuccessHandler(new CMToolSuccessHandler("/cmtv1web/home",userAuthenticateService));
    }
@Override
    public Authentication attemptAuthentication(HttpServletRequest request,
                                                HttpServletResponse response) throws AuthenticationException {
       //写你自己的登录验证逻辑
       .....
       UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
                username, "");
        setDetails(request, authRequest);
        return super.getAuthenticationManager().authenticate(authRequest);
    }
    //指定authenticationManager
    @Override
    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
        super.setAuthenticationManager(authenticationManager);
    }

CMToolAuthenticationProvider

 @Autowired
    UserAuthenticateService userAuthenticateService;

   
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        List<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
       //写自己的一些给用户加角色的逻辑
        UserBean userBean = userAuthenticateService.getUser(username);
        if(userBean!=null) {
            //将user的角色交给spring security备用
            List<RoleBean> roles = userBean.getRoles();
            if(roles!=null&&roles.size()>0){
                for(RoleBean role:roles){
                    authorities.add(new SimpleGrantedAuthority(role.getRole_name()));
                }
            }
        }
        return new UsernamePasswordAuthenticationToken(username, "", authorities);
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.isAssignableFrom(UsernamePasswordAuthenticationToken.class);
    }

spring session redis的整合, 有时间再写吧!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值