关于后端:配置-Spring-Security-登录后重定向到不同的页面

4次阅读

共计 4671 个字符,预计需要花费 12 分钟才能阅读完成。

1。概述

Web 应用程序的一个常见要求是 在登录后将不同类型的用户重定向到不同的页面。例如,将规范用户重定向到 /homepage.html 页面和将管理员用户重定向到 /console.html 页面。

本文将展现如何应用 Spring Security 疾速平安地实现此机制。这篇文章也是建设在 Spring MVC 教程 之上的,该教程波及设置我的项目所需的核心内容。

2。Spring 平安配置

Spring Security 提供了一个组件,该组件间接负责决定在胜利验证后做什么——AuthenticationSuccessHandler

2.1。根本配置

让咱们首先配置一个根本的 @Configuration@Service 类:

@Configuration
@EnableWebSecurity
public class SecSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            // ... endpoints
            .formLogin()
                .loginPage("/login.html")
                .loginProcessingUrl("/login")
                .defaultSuccessUrl("/homepage.html", true)
            // ... other configuration       
    }
}

此配置中要关注的局部是 defaultSuccessUrl() 办法。胜利登录后,任何用户都将被重定向到 homepage.html

此外,咱们须要配置用户及其角色。出于本文的目标,咱们将实现一个简略的UserDetailService,其中有两个用户,每个用户都有一个角色。无关此主题的更多信息,请浏览咱们的文章 Spring Security — Roles and Privileges。

@Service
public class MyUserDetailsService implements UserDetailsService {private Map<String, User> roles = new HashMap<>();

    @PostConstruct
    public void init() {roles.put("admin2", new User("admin", "{noop}admin1", getAuthority("ROLE_ADMIN")));
        roles.put("user2", new User("user", "{noop}user1", getAuthority("ROLE_USER")));
    }

    @Override
    public UserDetails loadUserByUsername(String username) {return roles.get(username);
    }

    private List<GrantedAuthority> getAuthority(String role) {return Collections.singletonList(new SimpleGrantedAuthority(role));
    }
}

另外请留神,在这个简略的示例中,咱们不会应用明码编码器。

2.2。增加自定义胜利处理程序

咱们当初有两个具备两个不同角色的用户:useradmin。胜利登录后,两者都将被重定向到 hompeage.html让咱们看看如何依据用户的角色进行不同的重定向。

首先,咱们须要将自定义胜利处理程序定义为 bean:

@Bean
public AuthenticationSuccessHandler myAuthenticationSuccessHandler(){return new MySimpleUrlAuthenticationSuccessHandler();
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
        // endpoints
        .formLogin()
            .loginPage("/login.html")
            .loginProcessingUrl("/login")
            .successHandler(myAuthenticationSuccessHandler())
        // other configuration      
}

2.3。XML 配置

在查看咱们的自定义胜利处理程序的实现之前,咱们还要查看等价的 XML 配置:

<http use-expressions="true" >
    <!-- other configuration -->
    <form-login login-page='/login.html' 
      authentication-failure-url="/login.html?error=true"
      authentication-success-handler-ref="myAuthenticationSuccessHandler"/>
    <logout/>
</http>

<beans:bean id="myAuthenticationSuccessHandler"
  class="com.baeldung.security.MySimpleUrlAuthenticationSuccessHandler" />

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="user1" password="{noop}user1Pass" authorities="ROLE_USER" />
            <user name="admin1" password="{noop}admin1Pass" authorities="ROLE_ADMIN" />
        </user-service>
    </authentication-provider>
</authentication-manager>

3。自定义身份验证胜利处理程序

除了 AuthenticationSuccessHandler 接口,Spring 还为这个策略组件提供了一个正当的默认值 – AbstractAuthenticationTargetUrlRequestHandler 和一个简略的实现 – SimpleUrlAuthenticationSuccessHandler。通常,这些实现将在登录后确定 URL 并执行到该 URL 的重定向。

尽管有些灵便,但确定此指标 URL 的机制不容许以编程形式进行确定——因而咱们将实现接口并提供胜利处理程序的自定义实现。此实现将依据用户的角色确定用户登录后重定向到的 URL。

首先,咱们须要重写 onAuthenticationSuccess 办法:

public class MySimpleUrlAuthenticationSuccessHandler
  implements AuthenticationSuccessHandler {protected Log logger = 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(request);
    }

咱们自定义的办法调用了两个辅助办法:

protected void handle(
        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);
}

以下办法执行理论工作并将用户映射到指标 URL:

protected String determineTargetUrl(final Authentication authentication) {Map<String, String> roleTargetUrlMap = new HashMap<>();
    roleTargetUrlMap.put("ROLE_USER", "/homepage.html");
    roleTargetUrlMap.put("ROLE_ADMIN", "/console.html");

    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();}

请留神,此办法将返回用户领有的第一个角色的映射 URL。因而,如果用户有多个角色,映射的 URL 将与 authorities 汇合中给出的第一个角色匹配。

protected void clearAuthenticationAttributes(HttpServletRequest request) {HttpSession session = request.getSession(false);
    if (session == null) {return;}
    session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
}

determineTargetUrl – 这是策略的外围 – 只需查看用户类型(由权限确定)并 依据此角色抉择指标 URL

因而,admin 用户 – 由 ROLE_ADMIN 权限确定 – 将在登录后重定向到控制台页面,而 规范用户 – 由 ROLE_USER 确定 – 将是重定向到主页。

4。论断

本文中提及的代码 [在 GitHub 上] (https://github.com/eugenp/tut…) 可用。这是一个基于 Maven 的我的项目,因而它应该很容易导入和运行。

正文完
 0