阅读 418

SpringSecurity学习 - 登录之后的重定向

简介

通常一个后台管理系统,会包含不同的角色和权限;

然后不同的角色,登录后会根据权限的不同,跳转到不同的界面;

这里我们还是设定有两个角色:普通用户和管理员;

  • 普通用户:登录成功跳转到 home 页面;

  • 管理员:登录成功跳转到 admin 页面;

目录

  • 基本配置

  • 配置用户和角色

  • 创建处理器类

  • 配置处理器

  • 修改控制器

  • 运行

正文

1. 基本配置

先配置一个默认的登录成功界面,如下所示:

@Configuration @EnableWebSecurity @Slf4j public class SecSecurityConfig extends WebSecurityConfigurerAdapter {     @Override     protected void configure(HttpSecurity http) throws Exception {         http             .authorizeRequests()             .formLogin()                 .loginPage("/login")              // 登录成功跳转的页面,第二个参数true表示每次登录成功都是跳转到home,如果false则表示跳转到登录之前访问的页面                 .defaultSuccessUrl("/home.html", true)             // ... 其他配置                  } } 复制代码

这样当用户登录成功后,会默认跳转到home.html界面;

但是本节我们要做的就是修改这个地方,使得不同角色跳转不到不同的界面;

下面开始进入主体

2. 配置用户和角色

这里我们用 全局配置:

 @Autowired     public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {         // 数据没有持久化,只是保存在内存中         auth.inMemoryAuthentication()                 .withUser("javalover").password(passwordEncoder().encode("123456")).roles("USER")                 .and()                 .withUser("admin").password(passwordEncoder().encode("123456")).roles("ADMIN");     } 复制代码

这里配置了两个用户:

  • 普通用户:javalover

  • 管理员:admin

3. 创建处理器类

第一步中的配置是:两个角色登录后,默认都是跳转到home.html界面;

接下来就开始修改,使他们跳转到不同的界面;

先定义一个处理器类,实现了AuthenticationSuccessHandler接口:

public class MySimpleUrlAuthenticationSuccessHandler         implements AuthenticationSuccessHandler {     private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();     @Override     public void onAuthenticationSuccess(HttpServletRequest request,                                         HttpServletResponse response, Authentication authentication)             throws IOException {          String targetUrl = determineTargetUrl(authentication);         if (response.isCommitted()) {             logger.debug(                     "Response has already been committed. Unable to redirect to "                             + targetUrl);             return;         }         redirectStrategy.sendRedirect(request, response, targetUrl);         } } 复制代码

覆写的onAuthenticationSuccess方法:登录成功会先到这个地方,然后我们就可以在这里控制下一步要跳转的界面(当然其他的一些操作也可以);

determineTargetUrl方法:就是这篇文章的核心;

它会根据不同的权限,获取到不同的跳转url,然后重定向;

protected String determineTargetUrl(final Authentication authentication) {     Map<String, String> roleTargetUrlMap = new HashMap<>();     roleTargetUrlMap.put("ROLE_USER", "/home");     roleTargetUrlMap.put("ROLE_ADMIN", "/admin");     final Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();     for (final GrantedAuthority grantedAuthority : authorities) {         String authorityName = grantedAuthority.getAuthority();         if(roleTargetUrlMap.containsKey(authorityName)) {             return roleTargetUrlMap.get(authorityName);         }     }     throw new IllegalStateException(); } 复制代码

4. 配置处理器

上面我们定义了一个处理器,用来控制登录成功后的跳转界面;

这里我们将其配置到config类中;

先在配置类中注入一个Bean:AuthenticationSuccessHandler ,返回的是刚才创建的处理器类

@Bean public AuthenticationSuccessHandler myAuthenticationSuccessHandler(){     return new MySimpleUrlAuthenticationSuccessHandler(); } 复制代码

然后替换掉开头设置的跳转url参数,如下所示:

@Override protected void configure(final HttpSecurity http) throws Exception {     http         .authorizeRequests()         .formLogin()             .loginPage("/login")             .successHandler(myAuthenticationSuccessHandler())         // ...其他配置 } 复制代码

5. 修改控制器

上面我们跳转home和admin,是通过控制器进行跳转的,下面我们配置一下控制器:

@Controller @Slf4j public class SecurityController {     @RequestMapping("/login")     public String login(){         log.info("=== login ===");         return "login";     }     @RequestMapping("/home")     public String home(Model model){         model.addAttribute("user", getUsername());         model.addAttribute("role", getAuthority());         return "home";     }     @RequestMapping("/admin")     public String admin(Model model){         model.addAttribute("user", getUsername());         model.addAttribute("role", getAuthority());         return "admin";     }     @RequestMapping("/accessDenied")     public String accessDenied(Model model){         model.addAttribute("user", getUsername());         model.addAttribute("role", getAuthority());         return "access_denied";     }     // 获取当前登录的用户名     private String getUsername(){         return SecurityContextHolder.getContext().getAuthentication().getName();     }     // 获取当前登录的用户角色     private String getAuthority(){         Collection<? extends GrantedAuthority> authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities();         ArrayList<String> list = new ArrayList<>();         for(GrantedAuthority authority: authorities){             list.add(authority.getAuthority());         }         log.info("=== authority:" + list);         return list.toString();     } } 复制代码

6. 运行

接下来我们就可以启动程序,访问http://localhost:8090/进行测试了

前端代码就不贴了,就是三个界面:login,.html, home.html, admin.html。完整源码见文末

  • 普通用户登录:

image-20211119123413681

跳转到home

image-20211119123425793

  • 管理员登录:

image-20211119123533315

跳转到admin

image-20211119123541475

总结

重定向的核心就是那个处理器中的determineTargetUrl方法,根据角色的不同,跳转到不同的界面;


作者:汤圆学Java
链接:https://juejin.cn/post/7032566211414065159

文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐