spring - 访问被拒绝(用户是匿名的);重定向到身份验证入口点

标签 spring angular

我正在尝试将 spring oauth2(基于 Java 的配置而不是引导)与 angular 6 集成,

我的 WebSecurityConfigurerAdapter.java 文件是:

package com.novowash.authentication;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.approval.ApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler;
import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class OAuth2SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private ClientDetailsService clientDetailsService;

    @Autowired
    NovoAuthenticationProvider novoAuthenticationProvider;

    @Autowired
    UserDetailsServiceImpl userDetailsServiceImpl;

    @Autowired
    private PasswordEncoder userPasswordEncoder;


    @Autowired
    @Qualifier("dataSource")
    DataSource dataSource;

    @Autowired
    public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
        /*auth.inMemoryAuthentication()
        .withUser("bill").password("abc123").roles("ADMIN").and()
        .withUser("bob").password("abc123").roles("USER");*/

        auth.authenticationProvider(novoAuthenticationProvider);
//      auth.userDetailsService(userDetailsServiceImpl).passwordEncoder(userPasswordEncoder);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .cors().and()
        .csrf().disable()
        .authorizeRequests()
        .antMatchers(HttpMethod.OPTIONS,"/oauth/token").permitAll()
        .antMatchers("/signup").permitAll()
        .anyRequest().authenticated()
        .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
    }

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


    @Bean
    public TokenStore tokenStore() {
        return new JdbcTokenStore(dataSource);
    }

    @Bean
    @Autowired
    public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore){
        TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
        handler.setTokenStore(tokenStore);
        handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
        handler.setClientDetailsService(clientDetailsService);
        return handler;
    }

    @Bean
    @Autowired
    public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
        TokenApprovalStore store = new TokenApprovalStore();
        store.setTokenStore(tokenStore);
        return store;
    }

}

我的身份验证提供程序是:
package com.novowash.authentication;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import com.novowash.Enums.CommonEnums;
import com.novowash.model.User;
import com.novowash.service.UserService;



/**
 * @author manish
 * 
 * This Class is responsible for authentication and 
 * access control of users to cube root Admin module over http in extension of AuthenticationProvider interface of Spring web framework .   

 *
 */
@Component("novoAuthenticationProvider")
public class NovoAuthenticationProvider implements AuthenticationProvider {

    private static final Logger logger = Logger.getLogger(NovoAuthenticationProvider.class);

    @Autowired UserService userService;

    /* (non-Javadoc)
     * @see org.springframework.security.authentication.AuthenticationProvider#authenticate(org.springframework.security.core.Authentication)
     */
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        try {
            logger.debug( "ImageVideoAuthenticationProvider.authenticate() authentication.getPrincipal(): " + authentication.getPrincipal());
            logger.debug( "ImageVideoAuthenticationProvider.authenticate() authentication.getCredentials(): " + authentication.getCredentials());

            String userName = authentication.getPrincipal().toString();
            String password = authentication.getCredentials().toString();

            User user = userService.findUserByMobile(userName);

            if (user == null) {
                throw new UsernameNotFoundException(String.format(URLEncoder.encode("Invalid Email OR password", "UTF-8"), authentication.getPrincipal()));
            }

            if (CommonEnums.STATUS.INACTIVE.ID == user.getStatus()) {
                throw new UsernameNotFoundException(String.format(URLEncoder.encode("You are not active", "UTF-8"), authentication.getPrincipal()));
            }

            if (CommonEnums.STATUS.BLOCK.ID == user.getStatus()) {
                throw new UsernameNotFoundException(String.format(URLEncoder.encode("You are blocked. Please contact admin", "UTF-8"), authentication.getPrincipal()));
            }
            List<String> roles=null;
            if(user != null){
             roles= userService.getUserRoles(user.getId());
            }
            List<GrantedAuthority> grantList= new ArrayList<GrantedAuthority>();
            if(roles!= null)  {
                for(String role: roles)  {
                    // ROLE_USER, ROLE_ADMIN,..
                    GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_" + role);
                    grantList.add(authority);
                }
            }  
            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user, password, grantList);
            return token;
        } catch (Exception e) {
            logger.error( "Error in ImageVideoAuthenticationProvider.authenticate()", e);
            throw new AuthenticationServiceException(e.getMessage());
        }
    }

    /* (non-Javadoc)
     * @see org.springframework.security.authentication.AuthenticationProvider#supports(java.lang.Class)
     */
    public boolean supports(Class<?> clazz) {
        return clazz.equals(UsernamePasswordAuthenticationToken.class);
    }

}

我已经添加了 CORSFilter.java 。

Angular 6 服务:
import { HttpClient, HttpHeaders, HttpParams } from "@angular/common/http";
import { Inject, Injectable } from "@angular/core";
import { OAuthService } from "angular-oauth2-oidc";
import { environment } from "../../environments/environment";
import { Observable } from "rxjs/Observable";
import { map, combineLatest } from 'rxjs/operators';

@Injectable()
export class ROPCService {
  private _user: any;

  constructor(private httpClient: HttpClient, private oauthService: OAuthService) {}

  public async login(username: string, password: string) {
    debugger;
    const body = new HttpParams()
      .set('username', username)
      .set('password', password)
      .set('grant_type', environment.auth.grantType);

    const headers = new HttpHeaders()
      .set("Content-type", "application/x-www-form-urlencoded; charset=utf-8")
      .set("Authorization", "Basic d2ViOnNlY3JldA==");

    this.httpClient
      .post(this.oauthService.tokenEndpoint, body.toString(), {headers:headers})
      .pipe(map((res: any) => {
        debugger;
      })).subscribe(
        data => {
          debugger;
        },
        err => {
          debugger;
        }
      )
  }

  public logOut() {
    if (this.oauthService.getRefreshToken() === null) {
      return;
    }
    const refreshToken = this.oauthService.getRefreshToken();
    const accessToken = this.oauthService.getAccessToken();

    this.oauthService.logOut(true);

    const body = new HttpParams().set("client_id", this.oauthService.clientId).set("refresh_token", refreshToken);

    return this.httpClient.post(this.oauthService.logoutUrl, body.toString(), {
      headers: new HttpHeaders().set("Content-Type", "application/x-www-form-urlencoded"),
    });
  }

  public get user() {
    return this._user;
  }
  public set user(user) {
    this._user = user;
  }
}

当我调用/oauth/token URL 时出现 401 错误,我的请求是:
call from web

我在后端遇到错误:

2018-08-02 11:52:09 DEBUG DefaultListableBeanFactory:251 - Returning cached instance of singleton bean 'delegatingApplicationListener' 2018-08-02 11:52:09 DEBUG ExceptionTranslationFilter:174 - Access is denied (user is anonymous); redirecting to authentication entry point org.springframework.security.access.AccessDeniedException: Access is denied at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84) at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:124) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:158) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748) 2018-08-02 11:52:09 DEBUG AndRequestMatcher:66 - Trying to match using Ant [pattern='/', GET] 2018-08-02 11:52:09 DEBUG AntPathRequestMatcher:137 - Request 'OPTIONS /oauth/token' doesn't match 'GET / 2018-08-02 11:52:09 DEBUG AndRequestMatcher:69 - Did not match 2018-08-02 11:52:09 DEBUG HttpSessionRequestCache:62 - Request not saved as configured RequestMatcher did not match 2018-08-02 11:52:09 DEBUG ExceptionTranslationFilter:203 - Calling Authentication entry point. 2018-08-02 11:52:09 DEBUG DelegatingAuthenticationEntryPoint:78 - Trying to match using MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@781f892e, matchingMediaTypes=[application/atom+xml, application/x-www-form-urlencoded, application/json, application/octet-stream, application/xml, multipart/form-data, text/xml], useEquals=false, ignoredMediaTypes=[/]] 2018-08-02 11:52:09 DEBUG MediaTypeRequestMatcher:185 - httpRequestMediaTypes=[] 2018-08-02 11:52:09 DEBUG MediaTypeRequestMatcher:213 - Did not match any media types 2018-08-02 11:52:09 DEBUG DelegatingAuthenticationEntryPoint:78 - Trying to match using AndRequestMatcher [requestMatchers=[NegatedRequestMatcher [requestMatcher=MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@781f892e, matchingMediaTypes=[text/html], useEquals=false, ignoredMediaTypes=[]]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@781f892e, matchingMediaTypes=[application/atom+xml, application/x-www-form-urlencoded, application/json, application/octet-stream, application/xml, multipart/form-data, text/xml], useEquals=false, ignoredMediaTypes=[/]]]] 2018-08-02 11:52:09 DEBUG AndRequestMatcher:66 - Trying to match using NegatedRequestMatcher [requestMatcher=MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@781f892e, matchingMediaTypes=[text/html], useEquals=false, ignoredMediaTypes=[]]] 2018-08-02 11:52:09 DEBUG MediaTypeRequestMatcher:185 - httpRequestMediaTypes=[] 2018-08-02 11:52:09 DEBUG MediaTypeRequestMatcher:213 - Did not match any media types 2018-08-02 11:52:09 DEBUG NegatedRequestMatcher:51 - matches = true 2018-08-02 11:52:09 DEBUG AndRequestMatcher:66 - Trying to match using MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@781f892e, matchingMediaTypes=[application/atom+xml, application/x-www-form-urlencoded, application/json, application/octet-stream, application/xml, multipart/form-data, text/xml], useEquals=false, ignoredMediaTypes=[/]] 2018-08-02 11:52:09 DEBUG MediaTypeRequestMatcher:185 - httpRequestMediaTypes=[] 2018-08-02 11:52:09 DEBUG MediaTypeRequestMatcher:213 - Did not match any media types 2018-08-02 11:52:09 DEBUG AndRequestMatcher:69 - Did not match 2018-08-02 11:52:09 DEBUG DelegatingAuthenticationEntryPoint:91 - No match found. Using default entry point org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint@5a1a107f 2018-08-02 11:52:09 DEBUG HstsHeaderWriter:130 - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@5b4e497d 2018-08-02 11:52:09 DEBUG SecurityContextPersistenceFilter:119 - SecurityContextHolder now cleared, as request processing completed

最佳答案

这正是您突出显示的错误所说的。您发送的请求方法是 GET 但它需要一个 OPTIONS 方法。

它在 OAuth2SecurityConfig 中配置:

.antMatchers(HttpMethod.OPTIONS,"/oauth/token").permitAll()

将其更改为 GET,它应该可以工作。
.antMatchers(HttpMethod.GET,"/oauth/token").permitAll()

关于spring - 访问被拒绝(用户是匿名的);重定向到身份验证入口点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51647147/

相关文章:

配置为使用 https 时 Spring 不启动

javascript - 如何在没有 ng-model 的情况下以编程方式更改 angular 2 形式的原始属性

node.js - Sqlite Electron : Error: SQLITE_CANTOPEN: unable to open database file

angular - 使用 Angular 7 Material CDK 进行嵌套拖放

javascript - 如何实现迭代、数组填充 Angular 2 输入?

java - 参数中带有 clob 的 oracle 过程(大文本)

java - Spring 4.2.3.RELEASE 和 Hibernate 5.0.4.Final 兼容性问题

java - net::ERR_CONTENT_LENGTH_MISMATCH - 加载 javascript 失败

java - 5.2 中的 spring AnnotationUtils 不再搜索父类?

即使使用 ChangeDetectionStrategy.OnPush 也会调用 Angular ngDoCheck()