gpt4 book ai didi

spring - AuthenticationCredentialsNotFoundException : An Authentication object was not found in the SecurityContext

转载 作者:行者123 更新时间:2023-12-02 06:58:29 25 4
gpt4 key购买 nike

我在我的服务器上实现了以下登录功能 this post基本上:

@Transactional
public void login(String userId, String password) {

LOGGER.debug("Login for " + userId);

User user = new User(userId, password, true, true, true, true, new ArrayList<GrantedAuthority>());

Authentication auth = new UsernamePasswordAuthenticationToken(user, password,
new ArrayList<GrantedAuthority>());

try {
auth = this.authenticationProvider.authenticate(auth);
} catch(BadCredentialsException e) {
LOGGER.debug("Bad credentials ..");
throw new RuntimeException(e.getMessage());
}

LOGGER.debug("User successfully authenticated [userId="+userId+"]");

SecurityContext sc = new SecurityContextImpl();
sc.setAuthentication(auth);

SecurityContextHolder.setContext(sc);
}

到目前为止,这似乎没有任何问题。但是,如果我在登录后立即执行此请求

@PreAuthorize("hasPermission('ADMIN')")
public void test(String msg) {
LOGGER.debug("test: " + msg);
}

结果是这里的异常:

Caused by: org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:378)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:222)
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:64)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
at com.mz.server.web.service.LoginService$$EnhancerBySpringCGLIB$$caf0e62d_2.test(<generated>)
at com.mz.server.web.servlet.LoginServletImpl.test(LoginServletImpl.java:99)

阅读有关 SecurityContextHolder.setContext() 的内容时说:

Associates a new SecurityContext with the current thread of execution.

所以我想我的问题是我不明白 Spring 如何召回刚刚登录到我的系统并且现在想要继续进行经过身份验证的请求的用户。

为什么我不直接重定向到 /login

<小时/>

Spring上下文:

<!-- //////////////////////////////////////////////////////////////////////////////// -->
<!-- // BEGIN Spring Security -->

<sec:http auto-config="true" use-expressions="true"/>

<bean id="httpSessionSecurityContextRepository" class='org.springframework.security.web.context.HttpSessionSecurityContextRepository'>
<property name='allowSessionCreation' value='false' />
</bean>

<bean id="securityContextPersistenceFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<constructor-arg ref="httpSessionSecurityContextRepository" />
</bean>

<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<constructor-arg>
<list>
<sec:filter-chain pattern="/**" filters="securityContextPersistenceFilter" />
</list>
</constructor-arg>
</bean>

<bean id="authenticationListener" class="com.mz.server.web.auth.CustomAuthenticationListener"/>

<bean id="authenticationProvider" class="com.mz.server.web.auth.CustomAuthenticationProvider"/>

<bean id="userDetailsService" class="com.mz.server.web.service.CustomUserDetailsService"/>

<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider ref="authenticationProvider"/>
</sec:authentication-manager>

<sec:global-method-security
authentication-manager-ref="authenticationManager"
pre-post-annotations="enabled"/>

<!-- // END Spring Security -->
<!-- //////////////////////////////////////////////////////////////////////////////// -->

web.xml

<!-- //////////////////////////////////////////////////////////////////////////////// -->
<!-- // BEGIN Filters -->

<!-- Spring Security -->

<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/**</url-pattern>
</filter-mapping>

<!-- // END FILTERS -->
<!-- //////////////////////////////////////////////////////////////////////////////// -->

最佳答案

我知道你的痛苦,我在弄清楚 Spring Security 方面花了很多时间。真的很值得争论。但您可能需要添加 SecurityContextPersistenceFilter。这通常会使用 JSessionID 中的 HttpSession 自动将您的凭据添加到 SecurityContext。我有一个自定义身份验证处理程序,因此我的代码中有一些不相关的额外部分,但我认为这可能会为您指明正确的方向。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">


<bean id="httpSessionSecurityContextRepository"
class='org.springframework.security.web.context.HttpSessionSecurityContextRepository'>
<property name='allowSessionCreation' value='false' />
</bean>

<bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<constructor-arg ref="httpSessionSecurityContextRepository" />
</bean>

<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<constructor-arg>
<list>
<sec:filter-chain pattern="/rest/**"
filters="securityContextPersistenceFilter" />
</list>
</constructor-arg>
</bean>

<sec:global-method-security
authentication-manager-ref="authenticationManager"
secured-annotations="enabled" />

关于spring - AuthenticationCredentialsNotFoundException : An Authentication object was not found in the SecurityContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34121873/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com