Spring Security两个角色的实现

时间:2018-02-18 16:37:00

标签: java spring spring-boot spring-security

我是Spring安全方法的新手。我试图在我的网络应用程序中实现两个用户。 (管理员角色和用户角色) 我有两个使用thymeleaf的重定向页面管理员应该放到/ admin / **,对于用户应该是/ user / **

我尝试使用@order(1)和order(2)添加两个spring安全类但仍然无法工作..我的目标是,如果用户登录并在我的安全性中具有角色,它应该重定向到正确的页。

请参阅下面的代码

spring.queries.users-query=select email, password, enabled from user where email=?
spring.queries.roles-query=select u.email, r.role from user u inner join user_role ur on (u.id=ur.user_id) inner join role r on(ur.role_id=r.role_id) where u.email=?

    @Override
protected void configure(AuthenticationManagerBuilder auth)
        throws Exception {
    auth.
        jdbcAuthentication()
            .usersByUsernameQuery(usersQuery)
            .authoritiesByUsernameQuery(rolesQuery)
            .dataSource(dataSource)
            .passwordEncoder(bCryptPasswordEncoder);
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .antMatchers("/").permitAll()
        .antMatchers("/login").permitAll()
        .antMatchers("/register").permitAll()
        .antMatchers("/confirm").permitAll()
        .antMatchers("/forgotpassword").permitAll()
        .antMatchers("/criminal/getAllWantedCriminal").permitAll()
        .antMatchers("/criminal/viewCriminal").permitAll()
        .antMatchers("/admin/**").hasAuthority("ADMIN")
        .antMatchers("/user/**").hasAuthority("USER")
        .anyRequest()
        .authenticated().and().csrf().disable().formLogin()
        .loginPage("/login").failureUrl("/login?error=true")
        .defaultSuccessUrl("/admin/home")
        .usernameParameter("email")
        .passwordParameter("password")
        .and().logout()
        .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
        .logoutSuccessUrl("/").and().exceptionHandling()
        .accessDeniedPage("/access-denied");
}

1 个答案:

答案 0 :(得分:1)

实现此目标的最简单方法是创建自定义org.springframework.security.web.authentication.AuthenticationSuccessHandler

在那里,一旦用户正确登录,你可以检查一下 Authentication对象有ROLE_ADMIN重定向到默认配置的成功网址(默认用户成功网址)或管理员网址。这是一个工作样本,扩展了org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;

public class RoleBasedAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler
        implements AuthenticationSuccessHandler {

    private String adminRoleTargetUrl;

    private String adminRoleAuthority;

    /**
     * @param defaultTargetUrl
     */
    public RoleBasedAuthenticationSuccessHandler(String defaultTargetUrl, String adminRoleTargetUrl, String adminRoleAuthority) {
        super(defaultTargetUrl);
        this.adminRoleTargetUrl = adminRoleTargetUrl;
        this.adminRoleAuthority = adminRoleAuthority;
    }

    /* (non-Javadoc)
     * @see org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler#onAuthenticationSuccess(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.springframework.security.core.Authentication)
     */
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {
        if(isAdmin(authentication)){
            this.getRedirectStrategy().sendRedirect(request, response, this.getAdminRoleTargetUrl());
            return;
        }
        super.onAuthenticationSuccess(request, response, authentication);
    }

    /**
     * @param authentication
     */
    protected boolean isAdmin(Authentication authentication) {
        for(GrantedAuthority authority : authentication.getAuthorities()){
            if(authority.getAuthority().equals(this.getAdminRoleAuthority())){
                return true;
            }
        }
        return false;
    }

    /**
     * @return the adminRoleTargetUrl
     */
    public String getAdminRoleTargetUrl() {
        return adminRoleTargetUrl;
    }

    /**
     * @return the adminRoleAuthority
     */
    public String getAdminRoleAuthority() {
        return adminRoleAuthority;
    }   

}

然后,更改安全配置类,以便在方法RoleBasedAuthenticationSuccessHandler中设置successHandler实例,而不是使用defaultSuccessUrl

@Override
    protected void configure(AuthenticationManagerBuilder auth)
            throws Exception {
        auth.
        jdbcAuthentication()
        .usersByUsernameQuery(usersQuery)
        .authoritiesByUsernameQuery(rolesQuery)
        .dataSource(dataSource)
        .passwordEncoder(bCryptPasswordEncoder);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
        .antMatchers("/").permitAll()
        .antMatchers("/login").permitAll()
        .antMatchers("/register").permitAll()
        .antMatchers("/confirm").permitAll()
        .antMatchers("/forgotpassword").permitAll()
        .antMatchers("/criminal/getAllWantedCriminal").permitAll()
        .antMatchers("/criminal/viewCriminal").permitAll()
        .antMatchers("/admin/**").hasAuthority("ADMIN")
        .antMatchers("/user/**").hasAuthority("USER")
        .anyRequest()
        .authenticated().and().csrf().disable().formLogin()
        .loginPage("/login").failureUrl("/login?error=true")
        .successHandler(this.getSuccessHandler())
        .usernameParameter("email")
        .passwordParameter("password")
        .and().logout()
        .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
        .logoutSuccessUrl("/").and().exceptionHandling()
        .accessDeniedPage("/access-denied");
    }

    private AuthenticationSuccessHandler getSuccessHandler() {
        return new RoleBasedAuthenticationSuccessHandler(
                    "/user/home",
                    "/admin/home",
                    "ROLE_ADMIN"                
                );

    }