角色基础身份验证和不同页面上的重定向请求

时间:2017-12-13 06:43:01

标签: java spring spring-security

我正在尝试实现基于Spring安全角色的身份验证,并根据用户的角色将用户重定向到不同的页面。如果admin中的用户将其重定向到admin / index.html,并且用户是开发人员,则将其重定向到developer / index.html。

为此,我尝试了下面的代码。我没有遇到任何异常,但不确定问题出在哪里。任何帮助表示赞赏!

的WebContent /管理/ index.html的

This is admin landing page

的WebContent /显影剂/ index.html中

This is developer landing page

的pom.xml

http://maven.apache.org/maven-v4_0_0.xsd">     4.0.0

<groupId>com.provm</groupId>
<artifactId>aws-vm-pro</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>aws-vm-pro</name>
<url>http://maven.apache.org</url>

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.2.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>4.0.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>4.0.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>net.bull.javamelody</groupId>
        <artifactId>javamelody-core</artifactId>
        <version>1.60.0</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.2</version>
    </dependency>
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <configuration>
                <warSourceDirectory>WebContent</warSourceDirectory>
                <failOnMissingWebXml>false</failOnMissingWebXml>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-maven-plugin</artifactId>
            <version>9.0.6.v20130930</version>
            <configuration>
                <webAppSourceDirectory>WebContent</webAppSourceDirectory>
                <httpConnector>
                    <port>8088</port>
                    <host>localhost</host>
                </httpConnector>
                <scanIntervalSeconds>10</scanIntervalSeconds>
            </configuration>
        </plugin>
    </plugins>
</build>

SecurityWebApplicationInitializer.java

package com.my.app;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

    public SecurityWebApplicationInitializer() {
        super(MvcConfig.class, SecurityConfig.class);
    }

}

MvcConfig.java

package com.my.app;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan(basePackages = "com.my.app")
public class MvcConfig {

    @Bean
    public CustomSuccessHandler getCustomSuccessHandler() {
        return new CustomSuccessHandler();
    }

    @Bean
    public MyUserDetailsService getMyUserDetailsService() {
        return new MyUserDetailsService();
    }

}

SecurityConfig.java

package com.my.app;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    CustomSuccessHandler customSuccessHandler;
    @Autowired
    MyUserDetailsService myUserDetailsService;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/").hasAnyRole("ADMIN", "DEVELOPER").antMatchers("/admin/**")
                .hasRole("ADMIN").antMatchers("/developer/**").hasRole("DEVELOPER").and().formLogin()
                .successHandler(customSuccessHandler).and().logout()
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout")).permitAll();
        http.csrf().disable();
    }

}

CustomSuccessHandler.java

package com.my.app;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

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.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

@Component
public class CustomSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    @Override
    protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
            throws IOException {
        String targetUrl = determineTargetUrl(authentication);
        if (response.isCommitted()) {
            System.out.println("Can't redirect");
            return;
        }
        redirectStrategy.sendRedirect(request, response, targetUrl);
    }

    protected String determineTargetUrl(Authentication authentication) {
        String url = "";
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        List<String> roles = new ArrayList<String>();
        for (GrantedAuthority a : authorities) {
            roles.add(a.getAuthority());
        }
        if (isAdmin(roles)) {
            url = "/admin/index.html";
        } else if (isDeveloper(roles)) {
            url = "/developer/index.html";
        }
        return url;
    }

    private boolean isAdmin(List<String> roles) {
        if (roles.contains("ROLE_ADMIN")) {
            return true;
        }
        return false;
    }

    private boolean isDeveloper(List<String> roles) {
        if (roles.contains("ROLE_DEVELOPER")) {
            return true;
        }
        return false;
    }

    public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
        this.redirectStrategy = redirectStrategy;
    }

    protected RedirectStrategy getRedirectStrategy() {
        return redirectStrategy;
    }

}

MyUserDetailsS​​ervice.java

package com.my.app;

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

@Component
public class MyUserDetailsService implements UserDetailsService {

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        String password = null;
        String[] authorities = new String[1];
        String admin = "admin";
        String developer = "developer";
        if (username.equals(admin)) {
            password = "admin";
            authorities[0] = "ADMIN";
        }
        if (username.equals(developer)) {
            password = "developer";
            authorities[1] = "DEVELOPER";
        }
        System.out.println(username + "=" + password + "=" + authorities);
        return new MyUserDetails(username, password, authorities);
    }

}

MyUserDetails.java

package com.my.app;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.List;

public class MyUserDetails implements UserDetails {
    private String username;
    private String password;
    private List<GrantedAuthority> grantedAuthorities;

    public MyUserDetails(String username, String password, String[] authorities) {
        this.username = username;
        this.password = password;
        this.grantedAuthorities = AuthorityUtils.createAuthorityList(authorities);
    }

    public Collection<? extends GrantedAuthority> getAuthorities() {
        return grantedAuthorities;
    }

    public String getPassword() {
        return password;
    }

    public String getUsername() {
        return username;
    }

    public boolean isAccountNonExpired() {
        return true;
    }

    public boolean isAccountNonLocked() {
        return true;
    }

    public boolean isCredentialsNonExpired() {
        return true;
    }

    public boolean isEnabled() {
        return true;
    }

}

1 个答案:

答案 0 :(得分:0)

我自己想通了。有两个问题:

1. While adding String [] authorities, I should have added authorities[0] instead of authorities[1].
2. In case of admin: authorities[0] = "ROLE_ADMIN", In case of developer authorities[0] = "ROLE_DEVELOPER".