Spring boot + Spring security oauth2(jwt token)+ angular5前端

时间:2018-01-07 12:20:38

标签: spring angular spring-boot spring-security jwt

我使用以下技术来处理登录,身份验证和授权目的: 春季启动 Spring Security Oauth2 jwt令牌(在一个端口3032本地运行) Angular-5是前端(端口4200在本地)

请找到以下配置文件

Application.class

@SpringBootApplication
public class Application {

public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}

application.properties

server.port: 3032
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5433/CommandCenter
spring.datasource.username=postgres
spring.datasource.password=admin
spring.jpa.generate-ddl=true

spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none

#Application specific
authentication.oauth.clientid=springSecurityClient
authentication.oauth.secret=P@ssw0rd
authentication.oauth.tokenValidityInSeconds=86400
spring.datasource.testOnBorrow=true
spring.datasource.validationQuery=SELECT 1

OAuth2ResourceServerConfig.class

@Configuration
@EnableResourceServer
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Autowired
private CustomAuthenticationEntryPoint customAuthenticationEntryPoint;

@Autowired
private CustomLogoutSuccessHandler customLogoutSuccessHandler;


@Override
public void configure(HttpSecurity http) throws Exception {
    http.exceptionHandling()
            .authenticationEntryPoint(customAuthenticationEntryPoint)
            .and()
            .logout()
            .logoutUrl("/oauth/logout")
            .logoutSuccessHandler(customLogoutSuccessHandler)
            .and()
            .csrf()
            .requireCsrfProtectionMatcher(
                    new AntPathRequestMatcher("/oauth/authorize"))
            .disable().headers().frameOptions().disable().and().sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
            .authorizeRequests().antMatchers("/registration")
            .hasRole(Authority.Admin.name()).antMatchers("/users")
            .hasRole(Authority.User.name());
}
}

OAuth2AuthorizationServerConfig.class

    @Configuration
    @EnableAuthorizationServer
    public class OAuth2AuthorizationServerConfig extends
        AuthorizationServerConfigurerAdapter implements EnvironmentAware {
    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;
    private static final String ENV_OAUTH = "authentication.oauth.";
    private static final String PROP_CLIENTID = "clientid";
    private static final String PROP_SECRET = "secret";
    private static final String PROP_TOKEN_VALIDITY_SECONDS = "tokenValidityInSeconds"; 
    private RelaxedPropertyResolver propertyResolver;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients)
            throws Exception {
        clients.inMemory()
                .withClient(propertyResolver.getProperty(PROP_CLIENTID))
                .scopes("read", "write")
                .autoApprove(true)
                .authorities(Authorities.ROLE_Admin.name(),
                        Authorities.ROLE_User.name())
                .authorizedGrantTypes("password", "refresh_token")
                .secret(propertyResolver.getProperty(PROP_SECRET))
                .accessTokenValiditySeconds(
                        propertyResolver.getProperty(
                                PROP_TOKEN_VALIDITY_SECONDS, Integer.class,
                                1800));
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints)
            throws Exception {
        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer(),
                accessTokenConverter()));
        endpoints.tokenStore(tokenStore()).tokenEnhancer(tokenEnhancerChain)
                .accessTokenConverter(accessTokenConverter())
                .authenticationManager(authenticationManager);
    }


    @Bean
    public TokenEnhancer tokenEnhancer() {
        return new CustomTokenEnhancer();
    }

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(
                new ClassPathResource("jwt.jks"),
                "JjbGllbnRfaWQiOiJyYWppdGhhcHAiLC".toCharArray());
        converter.setKeyPair(keyStoreKeyFactory.getKeyPair("jwt"));
        return converter;
    }


    @Override
    public void setEnvironment(Environment environment) {
        this.propertyResolver = new RelaxedPropertyResolver(environment,
                ENV_OAUTH);
    }

    }

网络安全配置

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@Autowired
private UserDetailsService userDetailsService;

@Bean
public PasswordEncoder passwordEncoder(){
    return new BCryptPasswordEncoder();
}

@Bean
public DaoAuthenticationProvider authProvider() {
    DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
    authProvider.setUserDetailsService(userDetailsService);
    authProvider.setPasswordEncoder(passwordEncoder());
    return authProvider;
}
@Autowired
public void configure(AuthenticationManagerBuilder auth)
        throws Exception {
    auth.authenticationProvider(authProvider());

}

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring();
}

@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
}
}

CORS过滤器配置

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCorsFilter implements Filter {

public SimpleCorsFilter() {
}

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    HttpServletResponse response = (HttpServletResponse) res;
    HttpServletRequest request = (HttpServletRequest) req;

    Enumeration<String> headerNames = request.getHeaderNames();

    if (headerNames != null) {
            while (headerNames.hasMoreElements()) {
                    System.out.println("Header: " + request.getHeader(headerNames.nextElement()));
            }
    }
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Origin, x-requested-with, Content-Type, Accept, Authorization");

    if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
        response.setStatus(HttpServletResponse.SC_OK);
    } else {
        chain.doFilter(req, res);
    }
}

@Override
public void init(FilterConfig filterConfig) {
}

@Override
public void destroy() {
}
}

前端角度为

login() {
if(this.auth.username && this.auth.password) {
    this.loginButton = true;
    this.LoginUnauthorized = false;
    this.authenticationService.login(this.auth.username, this.auth.password)
        .subscribe(
            data => {
                if (data) {
                    this.cookieService.set('access_token', data.access_token);
                    this.cookieService.set('refresh_token', data.refresh_token);
                    this.cookieService.set('jti', data.jti);
                     this.cookieService.set('token_type',data.token_type)
                     this.cookieService.set('scope',data.scope);
                     this.cookieService.set('loginUser',this.auth.username);
                    this.authenticationService.getLoggedInUserRoles().subscribe(
    data => console.log(data),
    err => console.log(err)
  );

                }
            },
            error => {
                this.LoginUnauthorized = true
                this.auth.username ="" , this.auth.password = "";
                this.loginButton = false;
            });
}
}
login(username: string, password: string) {

    let headers = new HttpHeaders();
    var urlBase = 'http://localhost:3032/oauth/token?grant_type=password&username=' + username +'&password=' + password;
headers = headers.append('Authorization', 'Basic ' + btoa('springSecurityClient' + ':' + 'P@ssw0rd'));
    return this.http.post<any>(urlBase, {username, password}, {headers:headers})
.map(res => {
    return res;
});

}

getLoggedInUserRoles() {
    var urlBase = 'http://localhost:3032/AuthUser/';      
    return this.http.get<any>(urlBase);     

}

来到我的prbm是

我可以使用http://localhost:4200

登录

但登录后需要通过

获取角色列表

http://localhost:4200/AuthUser

我在浏览器中遇到以下错误,再次重定向到登录页面请帮我解决此问题。

HttpErrorResponse {headers: HttpHeaders, status: 200, statusText: "OK", url: "http://localhost:3032/login", ok: false, …}
error
:
{error: SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse (<anonymous>) at XMLHttp…, text: "<html><head><title>Login Page</title></head><body …b-f01c9e439632" />↵</table>↵</form></body></html>"}
headers
:
HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
message
:
"Http failure during parsing for http://localhost:3032/login"
name
:
"HttpErrorResponse"
ok
:
false
status
:
200
statusText
:
"OK"
url
:
"http://localhost:3032/login"
__proto__
:
HttpResponseBase

尝试直接访问 localhost:3032 时可以获得角色

在SoapUI中,我可以看到如下错误

  

{&#34; timestamp&#34;:1515303716945,&#34; status&#34;:403,&#34; error&#34;:   &#34;禁止&#34;,&#34;消息&#34;:&#34;无法验证提供的CSRF令牌   因为找不到您的会话。&#34;,&#34;路径&#34;:&#34; / AuthUser&#34; }

0 个答案:

没有答案