首页 > 解决方案 > 尝试通过 Spring Security 验证 json Bearer 标头时收到 403 禁止

问题描述

所以我有几个模块。我有一个发现服务模块,一个连接到发现服务的客户端模块,我还有一个 zuul 网关模块。

client 和 zuul 模块都有自己的 spring security 实例。

客户端模块在内存数据库中有一个 h2 依赖于它,并且在创建新用户时,用户将其所有信息都存储在数据库中。

我也在使用邮递员。我有一些我在邮递员中使用的方法。

  1. 创建一个新用户:< - 效果很好

    (这个http请求调用我在我的用户模块中创建的控制器bean,它使用用户名密码等创建用户实体并将其存储到h2数据库中)

  2. 用户登录:< - 效果很好

(这个对 /login 的邮递员 http 请求将触发 Spring Security 尝试登录。它通过从 json 格式的 http 请求中获取电子邮件和密码来做到这一点。然后在标头中向邮递员返回一个由 authenticationManager 创建的令牌)

  1. 检查用户状态:< - 工作不太好(这是问题开始的地方。这是调用用户/检查由我的 zuul 网关控制的访问。我可以将我的 ide 置于调试模式并观察我从邮递员传递令牌进入身份验证管理器。它接收令牌并进入解析器,但它说它在 .parseClaimsJws(token) 行之后打破了解析。)

这是我在这里的第一篇文章,很抱歉日志转储的格式可能是错误的,但如果有人想发表评论并告诉我如何解决,我会的。

我已经包含了一些日志记录以观察数据传递并查看用户和令牌正在按预期生成,我相信它们是,但我真的只是在学习 spring 及其所有组件。因此,如果我已经在我的安全 bean 类中完成了其他所有操作,那么可能会出现什么问题?我假设我缺少某种元数据,或者可能是属性文件中的某些内容,其中披露了在哪里可以找到现有令牌的位置?我还想知道 zuul 安全模块将如何继承知道其他模块创建的令牌除了通过网关主中的 @EnableZuulProxy 之外不相关时它们是什么?

这里是创建一个用户(这个方法来自用户模块):

@Override
    public UserDto createUser(UserDto userDetails) {
        log.info("creating user...{}",userDetails.toString());
        userDetails.setUserId(UUID.randomUUID().toString());
    userDetails.setEncryptedPassword(bCryptPasswordEncoder.encode(userDetails.getPassword()));

    ModelMapper modelMapper = new ModelMapper();

    modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);

    UserEntity userEntity = modelMapper.map(userDetails, UserEntity.class);

    usersRepository.save(userEntity);
    UserDto returnValue = modelMapper.map(userEntity, UserDto.class);

    return returnValue;
}

创建用户日志:

[http-nio-auto-1-exec-1] INFO  c.a.p.a.u.s.UsersServiceImpl - creating user...UserDto(firstName=FirstNameTest, lastName=LastNameTest, email=email@email.com, password=passwordTest, userId=null, encryptedPassword=null) 
[http-nio-auto-1-exec-1] DEBUG o.s.d.r.c.s.TransactionalRepositoryProxyPostProcessor$CustomAnnotationTransactionAttributeSource - Adding transactional method 'save' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 
[http-nio-auto-1-exec-1] DEBUG o.s.o.j.JpaTransactionManager - Found thread-bound EntityManager [SessionImpl(1254735951<open>)] for JPA transaction 
[http-nio-auto-1-exec-1] DEBUG o.s.o.j.JpaTransactionManager - Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 
[http-nio-auto-1-exec-1] DEBUG o.h.e.t.i.TransactionImpl - On TransactionImpl creation, JpaCompliance#isJpaTransactionComplianceEnabled == false 
[http-nio-auto-1-exec-1] DEBUG o.h.e.t.i.TransactionImpl - begin 
[http-nio-auto-1-exec-1] DEBUG o.s.o.j.JpaTransactionManager - Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@2d8854a4] 
[http-nio-auto-1-exec-1] DEBUG o.s.b.CachedIntrospectionResults - Not strongly caching class [com.appsdeveloperblog.photoapp.api.users.data.UserEntity] because it is not cache-safe 
[http-nio-auto-1-exec-1] DEBUG o.hibernate.SQL - call next value for hibernate_sequence 
[http-nio-auto-1-exec-1] DEBUG o.h.i.e.SequenceStructure - Sequence value obtained: 1 
[http-nio-auto-1-exec-1] DEBUG o.h.r.j.i.ResourceRegistryStandardImpl - HHH000387: ResultSet's statement was not registered 
[http-nio-auto-1-exec-1] DEBUG o.h.e.i.AbstractSaveEventListener - Generated identifier: 1, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator 
[http-nio-auto-1-exec-1] DEBUG o.s.o.j.JpaTransactionManager - Initiating transaction commit 
[http-nio-auto-1-exec-1] DEBUG o.s.o.j.JpaTransactionManager - Committing JPA transaction on EntityManager [SessionImpl(1254735951<open>)] 
[http-nio-auto-1-exec-1] DEBUG o.h.e.t.i.TransactionImpl - committing 
[http-nio-auto-1-exec-1] DEBUG o.h.e.i.AbstractFlushingEventListener - Processing flush-time cascades 
[http-nio-auto-1-exec-1] DEBUG o.h.e.i.AbstractFlushingEventListener - Dirty checking collections 
[http-nio-auto-1-exec-1] DEBUG o.h.e.i.AbstractFlushingEventListener - Flushed: 1 insertions, 0 updates, 0 deletions to 1 objects 
[http-nio-auto-1-exec-1] DEBUG o.h.e.i.AbstractFlushingEventListener - Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections 
[http-nio-auto-1-exec-1] DEBUG o.h.i.u.EntityPrinter - Listing entities: 
[http-nio-auto-1-exec-1] DEBUG o.h.i.u.EntityPrinter - com.appsdeveloperblog.photoapp.api.users.data.UserEntity{firstName=FirstNameTest, lastName=LastNameTest, id=1, userId=5bc8d277-2b54-45e0-8419-fe220d6cf6ed, email=email@email.com, encryptedPassword=$2a$10$RlEUYpkZ..w2XHQfhCbQH.bpF84B2Cnq2CLLicV7MnEg1ZQd2.JGu} 
[http-nio-auto-1-exec-1] DEBUG o.hibernate.SQL - insert into users (email, encrypted_password, first_name, last_name, user_id, id) values (?, ?, ?, ?, ?, ?) 
[http-nio-auto-1-exec-1] DEBUG o.s.o.j.JpaTransactionManager - Not closing pre-bound JPA EntityManager after transaction 
[http-nio-auto-1-exec-1] DEBUG o.s.w.s.m.m.a.HttpEntityMethodProcessor - Using 'application/json', given [application/json] and supported [application/json] 
[http-nio-auto-1-exec-1] DEBUG o.s.w.s.m.m.a.HttpEntityMethodProcessor - Writing [CreateUserResponseModel(firstName=FirstNameTest, lastName=LastNameTest, email=email@email.com, userI (truncated)...] 
[http-nio-auto-1-exec-1] DEBUG o.s.s.w.h.w.HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@1ec98ba9 
[http-nio-auto-1-exec-1] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession. 
[http-nio-auto-1-exec-1] DEBUG o.s.o.j.s.OpenEntityManagerInViewInterceptor - Closing JPA EntityManager in OpenEntityManagerInViewInterceptor 
[http-nio-auto-1-exec-1] DEBUG o.s.w.s.DispatcherServlet - Completed 201 CREATED 

这是来自用户模块的成功身份验证方法:

@Override
    public Authentication attemptAuthentication(
            HttpServletRequest request,
            HttpServletResponse response)
            throws AuthenticationException {
        log.info("attempting authentication");
    try {
        log.info("reading input stream with object mapper.");
        LoginRequestModel creds = new ObjectMapper()
                .readValue(request.getInputStream(), LoginRequestModel.class);
        log.info("creds email = {}",creds.getEmail());
        log.info("creds password = {}", creds.getPassword());

        log.info("calling getAuthenticationManager() from inside attemptAuthentication method");
        return getAuthenticationManager().authenticate(
                new UsernamePasswordAuthenticationToken(
                        creds.getEmail(),
                        creds.getPassword(),
                        new ArrayList<>()
                )
        );


    } catch (IOException e) {
        e.printStackTrace();
        throw new RuntimeException();
    }

}

@Override
protected void successfulAuthentication(HttpServletRequest request,
                                        HttpServletResponse response,
                                        FilterChain chain,
                                        Authentication authResult) throws IOException, ServletException {
    log.info("AUTHENTICATION SUCCESS");

    String username = ((User) authResult.getPrincipal()).getUsername();
    log.info("creating token for user {}", username);

    UserDto userDetails = usersService.getUserDetailsByEmail(username);
    log.info("userid = {}",userDetails.getUserId());
    log.info("password = {}",userDetails.getPassword());
    log.info("email = {}",userDetails.getEmail());
    log.info("encrypted password = {}",userDetails.getEncryptedPassword());
    log.info("first name = {}",userDetails.getFirstName());
    log.info("last name = {}",userDetails.getLastName());

    log.info("creating token using jwts builder");

    String token = Jwts.builder()
            .setSubject(userDetails.getUserId())
            .setExpiration(new Date(System.currentTimeMillis() + Long.parseLong(environment.getProperty("token.expiration_time"))))
            .signWith(SignatureAlgorithm.HS512, environment.getProperty("token.secret"))
            .compact();

    log.info("adding token to header: {}",token);
    log.info("adding userId to header: {}",userDetails.getUserId());

    response.addHeader("token", token);
    response.addHeader("userId", userDetails.getUserId());

}

及其产生的日志:

[http-nio-auto-1-exec-2] INFO  c.a.p.a.u.s.AuthenticationFilter - attempting authentication 
[http-nio-auto-1-exec-2] INFO  c.a.p.a.u.s.AuthenticationFilter - reading input stream with object mapper. 
[http-nio-auto-1-exec-2] INFO  c.a.p.a.u.s.AuthenticationFilter - creds email = email@email.com 
[http-nio-auto-1-exec-2] INFO  c.a.p.a.u.s.AuthenticationFilter - creds password = passwordTest 
[http-nio-auto-1-exec-2] INFO  c.a.p.a.u.s.AuthenticationFilter - calling getAuthenticationManager() from inside attemptAuthentication method 
[http-nio-auto-1-exec-2] DEBUG o.s.s.a.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider 
[http-nio-auto-1-exec-2] INFO  c.a.p.a.u.s.UsersServiceImpl - loading user by username: email@email.com 
[http-nio-auto-1-exec-2] DEBUG o.s.o.j.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler - Creating new EntityManager for shared EntityManager invocation 
[http-nio-auto-1-exec-2] DEBUG o.h.q.c.i.CriteriaQueryImpl - Rendered criteria query -> select generatedAlias0 from UserEntity as generatedAlias0 where generatedAlias0.email=:param0 
[http-nio-auto-1-exec-2] DEBUG o.h.h.i.QueryTranslatorFactoryInitiator - QueryTranslatorFactory : org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory@1ac68724 
[http-nio-auto-1-exec-2] INFO  o.h.h.i.QueryTranslatorFactoryInitiator - HHH000397: Using ASTQueryTranslatorFactory 
[http-nio-auto-1-exec-2] DEBUG o.h.h.i.a.QueryTranslatorImpl - parse() - HQL: select generatedAlias0 from com.appsdeveloperblog.photoapp.api.users.data.UserEntity as generatedAlias0 where generatedAlias0.email=:param0 
[http-nio-auto-1-exec-2] DEBUG o.h.h.i.a.ErrorTracker - throwQueryException() : no errors 
[http-nio-auto-1-exec-2] DEBUG o.h.h.i.a.QueryTranslatorImpl - --- HQL AST ---
 \-[QUERY] Node: 'query'
    +-[SELECT_FROM] Node: 'SELECT_FROM'
    |  +-[FROM] Node: 'from'
    |  |  \-[RANGE] Node: 'RANGE'
    |  |     +-[DOT] Node: '.'
    |  |     |  +-[DOT] Node: '.'
    |  |     |  |  +-[DOT] Node: '.'
    |  |     |  |  |  +-[DOT] Node: '.'
    |  |     |  |  |  |  +-[DOT] Node: '.'
    |  |     |  |  |  |  |  +-[DOT] Node: '.'
    |  |     |  |  |  |  |  |  +-[IDENT] Node: 'com'
    |  |     |  |  |  |  |  |  \-[IDENT] Node: 'appsdeveloperblog'
    |  |     |  |  |  |  |  \-[IDENT] Node: 'photoapp'
    |  |     |  |  |  |  \-[IDENT] Node: 'api'
    |  |     |  |  |  \-[IDENT] Node: 'users'
    |  |     |  |  \-[IDENT] Node: 'data'
    |  |     |  \-[IDENT] Node: 'UserEntity'
    |  |     \-[ALIAS] Node: 'generatedAlias0'
    |  \-[SELECT] Node: 'select'
    |     \-[IDENT] Node: 'generatedAlias0'
    \-[WHERE] Node: 'where'
       \-[EQ] Node: '='
          +-[DOT] Node: '.'
          |  +-[IDENT] Node: 'generatedAlias0'
          |  \-[IDENT] Node: 'email'
          \-[COLON] Node: ':'
             \-[IDENT] Node: 'param0'
 
[http-nio-auto-1-exec-2] DEBUG o.h.h.i.a.HqlSqlBaseWalker - select << begin [level=1, statement=select] 
[http-nio-auto-1-exec-2] DEBUG o.h.h.i.a.t.FromElement - FromClause{level=1} : com.appsdeveloperblog.photoapp.api.users.data.UserEntity (generatedAlias0) -> userentity0_ 
[http-nio-auto-1-exec-2] DEBUG o.h.h.i.a.t.FromReferenceNode - Resolved : generatedAlias0 -> userentity0_.id 
[http-nio-auto-1-exec-2] DEBUG o.h.h.i.a.t.FromReferenceNode - Resolved : generatedAlias0 -> userentity0_.id 
[http-nio-auto-1-exec-2] DEBUG o.h.h.i.a.t.DotNode - getDataType() : email -> org.hibernate.type.StringType@28a70766 
[http-nio-auto-1-exec-2] DEBUG o.h.h.i.a.t.FromReferenceNode - Resolved : generatedAlias0.email -> userentity0_.email 
[http-nio-auto-1-exec-2] DEBUG o.h.h.i.a.HqlSqlBaseWalker - select : finishing up [level=1, statement=select] 
[http-nio-auto-1-exec-2] DEBUG o.h.h.i.a.HqlSqlWalker - processQuery() :  ( SELECT ( {select clause} userentity0_.id ) ( FromClause{level=1} users userentity0_ ) ( where ( = ( userentity0_.email userentity0_.id email ) ? ) ) ) 
[http-nio-auto-1-exec-2] DEBUG o.h.h.i.a.u.JoinProcessor - Using FROM fragment [users userentity0_] 
[http-nio-auto-1-exec-2] DEBUG o.h.h.i.a.HqlSqlBaseWalker - select >> end [level=1, statement=select] 
[http-nio-auto-1-exec-2] DEBUG o.h.h.i.a.QueryTranslatorImpl - --- SQL AST ---
 \-[SELECT] QueryNode: 'SELECT'  querySpaces (users)
    +-[SELECT_CLAUSE] SelectClause: '{select clause}'
    |  +-[ALIAS_REF] IdentNode: 'userentity0_.id as id1_0_' {alias=generatedAlias0, className=com.appsdeveloperblog.photoapp.api.users.data.UserEntity, tableAlias=userentity0_}
    |  \-[SQL_TOKEN] SqlFragment: 'userentity0_.email as email2_0_, userentity0_.encrypted_password as encrypte3_0_, userentity0_.first_name as first_na4_0_, userentity0_.last_name as last_nam5_0_, userentity0_.user_id as user_id6_0_'
    +-[FROM] FromClause: 'from' FromClause{level=1, fromElementCounter=1, fromElements=1, fromElementByClassAlias=[generatedAlias0], fromElementByTableAlias=[userentity0_], fromElementsByPath=[], collectionJoinFromElementsByPath=[], impliedElements=[]}
    |  \-[FROM_FRAGMENT] FromElement: 'users userentity0_' FromElement{explicit,not a collection join,not a fetch join,fetch non-lazy properties,classAlias=generatedAlias0,role=null,tableName=users,tableAlias=userentity0_,origin=null,columns={,className=com.appsdeveloperblog.photoapp.api.users.data.UserEntity}}
    \-[WHERE] SqlNode: 'where'
       \-[EQ] BinaryLogicOperatorNode: '='
          +-[DOT] DotNode: 'userentity0_.email' {propertyName=email,dereferenceType=PRIMITIVE,getPropertyPath=email,path=generatedAlias0.email,tableAlias=userentity0_,className=com.appsdeveloperblog.photoapp.api.users.data.UserEntity,classAlias=generatedAlias0}
          |  +-[ALIAS_REF] IdentNode: 'userentity0_.id' {alias=generatedAlias0, className=com.appsdeveloperblog.photoapp.api.users.data.UserEntity, tableAlias=userentity0_}
          |  \-[IDENT] IdentNode: 'email' {originalText=email}
          \-[NAMED_PARAM] ParameterNode: '?' {name=param0, expectedType=org.hibernate.type.StringType@28a70766}
 
[http-nio-auto-1-exec-2] DEBUG o.h.h.i.a.ErrorTracker - throwQueryException() : no errors 
[http-nio-auto-1-exec-2] DEBUG o.h.h.i.a.QueryTranslatorImpl - HQL: select generatedAlias0 from com.appsdeveloperblog.photoapp.api.users.data.UserEntity as generatedAlias0 where generatedAlias0.email=:param0 
[http-nio-auto-1-exec-2] DEBUG o.h.h.i.a.QueryTranslatorImpl - SQL: select userentity0_.id as id1_0_, userentity0_.email as email2_0_, userentity0_.encrypted_password as encrypte3_0_, userentity0_.first_name as first_na4_0_, userentity0_.last_name as last_nam5_0_, userentity0_.user_id as user_id6_0_ from users userentity0_ where userentity0_.email=? 
[http-nio-auto-1-exec-2] DEBUG o.h.h.i.a.ErrorTracker - throwQueryException() : no errors 
[http-nio-auto-1-exec-2] DEBUG o.hibernate.SQL - select userentity0_.id as id1_0_, userentity0_.email as email2_0_, userentity0_.encrypted_password as encrypte3_0_, userentity0_.first_name as first_na4_0_, userentity0_.last_name as last_nam5_0_, userentity0_.user_id as user_id6_0_ from users userentity0_ where userentity0_.email=? 
[http-nio-auto-1-exec-2] DEBUG o.h.l.Loader - Result set row: 0 
[http-nio-auto-1-exec-2] DEBUG o.h.l.Loader - Result row: EntityKey[com.appsdeveloperblog.photoapp.api.users.data.UserEntity#1] 
[http-nio-auto-1-exec-2] DEBUG o.h.e.i.TwoPhaseLoad - Resolving associations for [com.appsdeveloperblog.photoapp.api.users.data.UserEntity#1] 
[http-nio-auto-1-exec-2] DEBUG o.h.e.i.TwoPhaseLoad - Done materializing entity [com.appsdeveloperblog.photoapp.api.users.data.UserEntity#1] 
[http-nio-auto-1-exec-2] INFO  c.a.p.a.u.s.AuthenticationFilter - AUTHENTICATION SUCCESS 
[http-nio-auto-1-exec-2] INFO  c.a.p.a.u.s.AuthenticationFilter - creating token for user email@email.com 
[http-nio-auto-1-exec-2] DEBUG o.s.o.j.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler - Creating new EntityManager for shared EntityManager invocation 
[http-nio-auto-1-exec-2] DEBUG o.h.q.c.i.CriteriaQueryImpl - Rendered criteria query -> select generatedAlias0 from UserEntity as generatedAlias0 where generatedAlias0.email=:param0 
[http-nio-auto-1-exec-2] DEBUG o.hibernate.SQL - select userentity0_.id as id1_0_, userentity0_.email as email2_0_, userentity0_.encrypted_password as encrypte3_0_, userentity0_.first_name as first_na4_0_, userentity0_.last_name as last_nam5_0_, userentity0_.user_id as user_id6_0_ from users userentity0_ where userentity0_.email=? 
[http-nio-auto-1-exec-2] DEBUG o.h.l.Loader - Result set row: 0 
[http-nio-auto-1-exec-2] DEBUG o.h.l.Loader - Result row: EntityKey[com.appsdeveloperblog.photoapp.api.users.data.UserEntity#1] 
[http-nio-auto-1-exec-2] DEBUG o.h.e.i.TwoPhaseLoad - Resolving associations for [com.appsdeveloperblog.photoapp.api.users.data.UserEntity#1] 
[http-nio-auto-1-exec-2] DEBUG o.h.e.i.TwoPhaseLoad - Done materializing entity [com.appsdeveloperblog.photoapp.api.users.data.UserEntity#1] 
[http-nio-auto-1-exec-2] INFO  c.a.p.a.u.s.UsersServiceImpl - found user in database by email. name: email@email.com 
[http-nio-auto-1-exec-2] INFO  c.a.p.a.u.s.AuthenticationFilter - userid = 5bc8d277-2b54-45e0-8419-fe220d6cf6ed 
[http-nio-auto-1-exec-2] INFO  c.a.p.a.u.s.AuthenticationFilter - password = $2a$10$RlEUYpkZ..w2XHQfhCbQH.bpF84B2Cnq2CLLicV7MnEg1ZQd2.JGu 
[http-nio-auto-1-exec-2] INFO  c.a.p.a.u.s.AuthenticationFilter - email = email@email.com 
[http-nio-auto-1-exec-2] INFO  c.a.p.a.u.s.AuthenticationFilter - encrypted password = $2a$10$RlEUYpkZ..w2XHQfhCbQH.bpF84B2Cnq2CLLicV7MnEg1ZQd2.JGu 
[http-nio-auto-1-exec-2] INFO  c.a.p.a.u.s.AuthenticationFilter - first name = FirstNameTest 
[http-nio-auto-1-exec-2] INFO  c.a.p.a.u.s.AuthenticationFilter - last name = LastNameTest 
[http-nio-auto-1-exec-2] INFO  c.a.p.a.u.s.AuthenticationFilter - creating token using jwts builder 
[http-nio-auto-1-exec-2] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Found key 'token.expiration_time' in PropertySource 'applicationConfig: [classpath:/application.properties]' with value of type String 
[http-nio-auto-1-exec-2] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Found key 'token.secret' in PropertySource 'configurationProperties' with value of type String 
[http-nio-auto-1-exec-2] INFO  c.a.p.a.u.s.AuthenticationFilter - adding token to header: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI1YmM4ZDI3Ny0yYjU0LTQ1ZTAtODQxOS1mZTIyMGQ2Y2Y2ZWQiLCJleHAiOjE1NjkwODc5MTF9.dGTH0D_ZdkGCWyU-1VsUW92299ZR5Udw_dySELVfpi-wUaXt1ZNWXfMhapVlVYNwqslTQ8pAi0ooB_AP61I6qw 
[http-nio-auto-1-exec-2] INFO  c.a.p.a.u.s.AuthenticationFilter - adding userId to header: 5bc8d277-2b54-45e0-8419-fe220d6cf6ed 
[http-nio-auto-1-exec-2] DEBUG o.s.s.w.h.w.HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@1ec98ba9 
[http-nio-auto-1-exec-2] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession. 
[http-nio-auto-1-exec-2] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed 

-- 我在 zuul gateway mmodule 中的 getAuth 方法:

 private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
        log.info("inside getAuthentication Method");
        log.info("requesting authentication path info from HttpServletRequest request path info = {}", request.getPathInfo());
        String authorizationHeader = request.getHeader(environment.getProperty("authorization.token.header.name"));
        log.info("authorization header = {}", authorizationHeader);


    if (authorizationHeader == null) {
        log.info("authorization eader was null, returning.");
        return null;
    }

    String token = authorizationHeader.replace(environment.getProperty("authorization.token.header.prefix"),new String());
    log.info("stripped prefix from bearer token, left with {}", token);

    log.info("parsing token... if successful will be returned as userId");
    log.info("parsing using key: {}", (environment.getProperty("token.secret")));
    String userId = Jwts.parser()
            // might need to set here the type of token?
            /*the user class uses this:
            * .signWith(SignatureAlgorithm.HS512, environment.getProperty("token.secret"))*/
            .setSigningKey(environment.getProperty("token.secret"))
            .parseClaimsJws(token)
            .getBody()
            .getSubject();

    log.info("parse successful! userId = {}" + userId);

    if (userId == null) {
        log.info("userId from http request was null!");
        return null;
    }
    log.info("returning userId = {}" + userId);

    return new UsernamePasswordAuthenticationToken(userId, null, new ArrayList<>());
}

}

-- 这是它产生的日志:

[http-nio-8011-exec-4] INFO  c.a.p.a.g.s.AuthorizationFilter - inside getAuthentication Method 
[http-nio-8011-exec-4] INFO  c.a.p.a.g.s.AuthorizationFilter - requesting authentication path info from HttpServletRequest request path info = null 
[http-nio-8011-exec-4] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Found key 'authorization.token.header.name' in PropertySource 'configurationProperties' with value of type String 
[http-nio-8011-exec-4] INFO  c.a.p.a.g.s.AuthorizationFilter - authorization header = BearereyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI1YmM4ZDI3Ny0yYjU0LTQ1ZTAtODQxOS1mZTIyMGQ2Y2Y2ZWQiLCJleHAiOjE1NjkwODc5MTF9.dGTH0D_ZdkGCWyU-1VsUW92299ZR5Udw_dySELVfpi-wUaXt1ZNWXfMhapVlVYNwqslTQ8pAi0ooB_AP61I6qw 
[http-nio-8011-exec-4] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Found key 'authorization.token.header.prefix' in PropertySource 'configurationProperties' with value of type String 
[http-nio-8011-exec-4] INFO  c.a.p.a.g.s.AuthorizationFilter - stripped prefix from bearer token, left with eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI1YmM4ZDI3Ny0yYjU0LTQ1ZTAtODQxOS1mZTIyMGQ2Y2Y2ZWQiLCJleHAiOjE1NjkwODc5MTF9.dGTH0D_ZdkGCWyU-1VsUW92299ZR5Udw_dySELVfpi-wUaXt1ZNWXfMhapVlVYNwqslTQ8pAi0ooB_AP61I6qw 
[http-nio-8011-exec-4] INFO  c.a.p.a.g.s.AuthorizationFilter - parsing token... if successful will be returned as userId 
[http-nio-8011-exec-4] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Found key 'token.secret' in PropertySource 'configurationProperties' with value of type String 
[http-nio-8011-exec-4] INFO  c.a.p.a.g.s.AuthorizationFilter - parsing using key: 375892173452876 
[http-nio-8011-exec-4] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Found key 'token.secret' in PropertySource 'configurationProperties' with value of type String 
[http-nio-8011-exec-4] DEBUG o.s.s.w.h.w.HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@3de0e6 
[http-nio-8011-exec-4] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed 
[http-nio-8011-exec-4] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Filter execution threw an exception] with root cause 

java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter


用户模块的 application.properties:

server.port=${PORT:0}
spring.application.name=users-ws
eureka.client.serviceUrl.defaultZone=http://localhost:8010/eureka
spring.devtools.restart.enabled=true
eureka.instance.instance-id=${spring.application.name}:${spring.application.instance_id:${random.value}}
spring.h2.console.enabled=true
spring.h2.console.settings.web-allow-others=true
spring.datasource.url=jdbc:h2:~/test

gateway.ip=192.168.1.12
/TEN DAYS
token.expiration_time=864000000
token.secret=375892173452876
login.url.path=/users/login

zuul 模块的 application.properties:

spring.application.name=zuul
server.port=8011
eureka.client.serviceUrl.defaultZone=http://localhost:8010/eureka
/Registration URL
api.registration.url-path=/users-ws/users
/Login URL
api.login.url-path=/users-ws/users/login
/H2 DB URL
api.h2-console.url-path=/users-ws/h2-console/**



authorization.token.header.name=Authorization

authorization.token.header.prefix=Bearer

token.secret=375892173452876

zuul 模块的安全配置:

@Configuration
@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {

    Environment environment;

    @Autowired
    public WebSecurity(Environment environment) {
        this.environment = environment;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().disable();
        http.headers().frameOptions().disable();
        http.authorizeRequests()
                .antMatchers(environment.getProperty("api.h2-console.url-path")).permitAll()
                .antMatchers(HttpMethod.POST, environment.getProperty("api.registration.url-path")).permitAll()
                .antMatchers(HttpMethod.POST, environment.getProperty("api.login.url-path")).permitAll()
                .anyRequest().authenticated()
                .and()
                .addFilter(new AuthorizationFilter(authenticationManager(), environment));

        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    }


}

我真的很想允许用户访问他们自己存储的个人数据,但是 spring security 不会识别我发送的不记名令牌!

标签: springspring-bootspring-securityspring-data-jpaspring-data

解决方案


解决它!

经过一天半的调试日志和堆栈溢出挖掘后,我发现问题是我在解析器上遇到类未找到异常。我了解到 java se 没有附带必要的库来解析令牌。它仅在 java ee 中是标准的。

jave se 用户必须将其添加到他们的 pom 文件中。

<dependency>
   <groupId>javax.xml.bind</groupId>
   <artifactId>jaxb-api</artifactId>
   <version>2.2.11</version>
</dependency>

推荐阅读