使用Spring Security在登录后重定向到不同的页面
最后修改:2020年8月15日
1.概述
Web应用程序的常见要求是登录后重定向不同类型的用户到不同的页面。这将是将标准用户重定向到的示例/ homepage.html页面和管理员用户到一个/ console.html页面为例。
本文将展示如何使用Spring Security快速和安全地实现这种机制。本文也建立在Spring MVC教程这涉及建立项目所需的核心MVC填充物。
2.Spring安全配置
Spring Security提供了一个组件,该组件直接负责决定成功身份验证后要做什么AuthenticationSuccessHandler。
2.1。基本配置
让我们首先配置一个basic@配置和@ service班级:
@configuration @enableWebSecurity公共类SecsecurityConfig扩展WebSecurityConfigurerAdapter {@Override保护的void配置(最终Httpsecurity HTTP)抛出异常{HTTP .AuthorizeRequests()// ...端点.formloglogin().loginpage(“/ login.html”).loginprocessingurl(“/ login”).defaultsuccessurl(“/ homepage.html”,true)// ...其他配置}}
这个配置要关注的部分是defaultsuccessurl()方法。成功登录后,任何用户都将被重定向到homepage.html。
此外,我们需要配置用户及其角色。出于本文的目的,我们将实现一个简单的userdetailservice.有两个用户,每个用户都有一个单一的角色。有关此主题的更多信息,请阅读我们的文章Spring Security -角色和特权。
@service public类myUserDetailsService实现userdetailsservice {私人地图<字符串,user>角色= new hashmap <>();@PostConstruct公共void init(){roles.put(“admin2”,新用户(“admin”,“{noop} admin1”,getauthority(“role_admin”)))));roles.put(“user2”,新用户(“用户”,“{noop} User1”,getauthority(“rome_user”))));@Override public userdetails loadUserByUsername(String用户名){return roles.get(用户名);私人列表 getauthorority(字符串角色){return collections.singleton onst(new splicalgrantedauthority(角色));}}
还要注意,在这个简单的示例中,我们不会使用密码编码器密码为前缀{noop}。
2.2。添加自定义成功处理程序
我们现在有两个用户有两个不同的角色:用户和行政。在成功登录后,两者都将被重定向到hompeage.html。让我们来看看我们如何根据用户的角色进行不同的重定向。
首先,我们需要将一个自定义的成功处理程序定义为bean:
@Bean public AuthenticationSuccessHandler(){返回新的MySimpleUrlAuthenticationSuccessHandler();}
然后替换defaultSuccessUrl电话成功手套方法,该方法接受我们的自定义成功处理程序作为参数:
@Override protected void configure(final HttpSecurity http) throws Exception {http .authorizeRequests() // endpoints .formLogin() .loginPage("/login.html") .loginProcessingUrl("/login") .successHandler(myAuthenticationSuccessHandler()) //其他配置}
2.3。XML配置
在查看自定义成功处理程序的实现之前,让我们先看看等价的XML配置:
<身份验证管理器> <身份验证提供者> <用户服务> <用户名= " user1 "密码= "{等待}user1Pass "当局= " ROLE_USER " / > <用户名=“admin1”密码= "{等待}admin1Pass "当局= " ROLE_ADMIN " / > < /用户服务> < /身份验证提供者> < /身份验证管理器>
3.自定义身份验证成功处理程序
除了AuthenticationSuccessHandler接口,Spring还为这个策略组件提供了一个明智的默认值AbstractAuthenticationTargetUrlRequestHandler和一个简单的实现-SimpleUrlAuthenticationSuccessHandler。通常,这些实现将在登录后确定URL并执行重定向到该URL。
虽然有点灵活,确定此目标URL的机制不允许以编程方式进行确定 - 因此我们将实现该接口并提供成功处理程序的自定义实现。此实现将根据用户的角色确定将用户重定向到登录后重定向到用户的URL。
首先,我们需要覆盖OnauthenticationSuccess.方法:
public class MySimpleUrlAuthenticationSuccessHandler implements AuthenticationSuccessHandler{受保护的日志记录器= LogFactory.getLog(this.getClass());private RedirectStrategy RedirectStrategy = new DefaultRedirectStrategy();@Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication Authentication) throws IOException {handle(request, response, Authentication);clearAuthenticationAttributes(请求);}
我们的自定义方法调用了两个辅助方法:
受保护的void句柄(httpservletrequest请求,httpservletresponse响应,身份验证身份验证)抛出ioException {String trounduRl =确定reticaleTargetURL(身份验证);if(response.iscommited()){logger.debug(“已提交响应。无法重定向到”+ Targeturl);返回;} redirectstrategy.sendredirect(请求,响应,targeturl);}
以下方法执行实际工作并将用户映射到目标URL:
受保护的字符串确定rArgetURL(最终身份验证身份验证){Map RoletargetURLMAP = New HashMap <>();roletargeturlmap.put(“rame_user”,“/homepage.html”);RoletArgetURLMAP.put(“role_admin”,“/console.html”);最后集合<?扩展授予授权>权限= Authentication.getAuthorities();for(最终GrantedAuthority GrantedAuthority:当局){String ProbitionName = grantedauthority.getauthority();if(roletargeturlmap.containskey(权限名称)){return roletargeturlmap.get(权限名称);}}抛出新的IllegalStateException();}
注意,该方法将返回用户拥有的第一个角色的映射URL。因此,如果一个用户有多个角色,映射的URL将与中的第一个角色匹配当局收藏。
受保护的void clearauthenticationAttributes(httpservletrequest请求){httpsession session = request.getsession(false);if(session == null){return;session.removeattribute(webattributes.authentication_exception);}
的determineTargetUrl- 这是策略的核心 - 只需查看用户类型(由权限决定)和根据这个角色选择目标URL。
所以,An.管理用户-由ROLE_ADMIN权限 - 登录后将重定向到控制台页面标准的用户-由ROLE_USER- 将被重定向到主页。
4.结论
与往常一样,本文提供的代码是可用的在github上。这是一个基于Maven的项目,因此应该易于导入和运行。