当前位置: 首页 > 知识库问答 >
问题:

Spring Security无法检索当前经过身份验证的用户

养昊天
2023-03-14

我正在开发一个使用Spring-Security的Spring-MVC应用程序。因为我需要获得当前认证用户的对象,这样我就可以使用setUser()方法。然而,该方法返回null,程序似乎会因null指针异常而崩溃。请看看代码。我已经调试了try-catch,它没有返回用户。

调用getCurrentlyAuthenticatedUser()引发了异常。我一查,说认证为空。

我通过实现接口User详细信息和UserDetailsService来实现Spring-Security。

人员类别:

@Entity
@Table(name="person")
public class Person implements UserDetails{

    private static final GrantedAuthority USER_AUTH = new SimpleGrantedAuthority("ROLE_USER");

    @Id
    @Column(name="id")
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "person_seq_gen")
    @SequenceGenerator(name = "person_seq_gen",sequenceName = "person_seq")
    private int id;


    @Column(name = "username")
    private String username;


    @Column(name = "password")
    private String password;

 @Transient
    private final String PERMISSION_PREFIX = "ROLE_USER";
    @Transient
    private List<GrantedAuthority> authorities;

    @Transient
    private String role;

@OneToMany(cascade = CascadeType.ALL,mappedBy = "person1")
  private Set<Notes> notes1;

    public Set<Notes> getNotes1() {
        return notes1;
    }

    public void setNotes1(Set<Notes> notes1) {
        this.notes1 = notes1;
    }
}

登录服务含义:

@Transactional
@Service("userDetailsService")
public class LoginServiceImpl implements UserDetailsService{

    @Autowired private PersonDAO personDAO;
    @Autowired private Assembler assembler;

    private static final GrantedAuthority USER_AUTH = new SimpleGrantedAuthority("ROLE_USER");

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException,DataAccessException {
        Person person = personDAO.findPersonByUsername(username);

        return assembler.buildUserFromUserEntity(person);
    }
}

汇编程序类:

@Service("汇编器")

public class Assembler {
    @Transactional(readOnly = true)
    User buildUserFromUserEntity(Person userEntity){
        String username = userEntity.getUsername();
        String password = userEntity.getPassword();

        // Long id = userEntity.getId();
        boolean enabled = userEntity.isActive();
        boolean accountNonExpired = userEntity.isAccountNonExpired();
        boolean credentialsNonExpired = userEntity.isCredentialsNonExpired();
        boolean accountNonLocked = userEntity.isAccountNonLocked();

        Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));

        User user = new User(username,password,enabled,accountNonExpired,credentialsNonExpired,accountNonLocked,authorities);
        return  user;
        }
}

//我在getPrincipal PersonServiceImpl的以下方法中得到错误:

@Service
public class PersonServiceImpl implements PersonService {

    private PersonDAO personDAO;
 @Override
    public Person getCurrentlyAuthenticatedUser() throws Exception{
        Authentication a = SecurityContextHolder.getContext().getAuthentication();
        Person currentUser = (Person) a.getPrincipal();
        if(currentUser == null){
            throw new Exception("No authenticated user retrieved");
        }else {
            System.out.println("We have currently authenticated user");
            return currentUser;
        }
    }

Spring Security-xml

    <import resource="servlet-context.xml" />

    <!-- Global Security settings -->
    <security:global-method-security pre-post-annotations="enabled" />

    <security:http pattern="/" security="none" />

    <security:http create-session="ifRequired" use-expressions="true" auto-config="false" disable-url-rewriting="true">
         <security:port-mappings>
        <security:port-mapping http="80" https="443"/>

    </security:port-mappings>
           <security:session-management session-fixation-protection="migrateSession" invalid-session-url="/invalidSession.html">
            <security:concurrency-control max-sessions="3" error-if-maximum-exceeded="true" expired-url="/sessionExpired.html"/>
        </security:session-management>
           <security:form-login login-page="/login" default-target-url="/note/add" always-use-default-target="true" authentication-failure-url="/login?error"/>

    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider user-service-ref="LoginServiceImpl" />

    </security:authentication-manager>

    <beans:bean id="daoAuthenticationProvider"
                class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
                <beans:property name="userDetailsService" ref="LoginServiceImpl"/>
    </beans:bean>


</beans>

共有1个答案

明安阳
2023-03-14

这仍然不是一个真正的答案,但太长了,无法放在评论中。

在使用从其他方法返回的对象之前,从不测试它们是否不为 null。我认为最可能的错误是SecurityContextHolder.getContext().getAuthentication();返回null导致下一行的NPE。如果这是真的,这意味着您的问题出在 Spring 安全性的配置中。但是,如果不看到bean userDetailsService,就不可能多说。你说你实现了userDetail和UserDetailsService,但没有说明如何实现。

我建议您删除remember_me,只要您没有可用的基本配置,即:

  • 您必须在访问受保护的页面之前登录
  • 您可以在SecurityContextHolder.getContext(). getAuth乐于()

一旦成功,你将增加更多的功能。如果没有,就很难找到问题的原因。

编辑:

你说错误发生在的行上,即人当前用户=(人)a.get主体();

Authentication a = SecurityContextHolder.getContext().getAuthentication();

getAuthentication()返回null。这意味着对于Spring Security性,当前没有经过身份验证的用户。

 类似资料:
  • 我的代码在这里:代码重新发布是因为我想问一个更直接的问题。如何在未经身份验证的用户和经过身份验证的用户之间切换?我的未经验证的文件似乎已缓存,我使用了以下方法: 在我剩下的api代码之前,它仍然不能工作。谢谢你的帮助 注意:我知道它不起作用,因为我在切换配置/凭据提供程序后立即使用lambda进行调用,并且只有授权用户才能调用此方法。 编辑@behrooziAWS答案: API代码: 完整错误:B

  • 我试图开发一个简单的后台应用程序连接到我的onedrive帐户(工作),并定期下载一些文件。 我遵循了以下教程https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-oauth-client-creds 我已经在这里注册了应用程序https://apps.dev.mi

  • 问题内容: 这是我的情况: 一个Web应用程序对许多应用程序执行某种SSO 登录的用户,而不是单击链接,该应用就会向正确的应用发布包含用户信息(名称,pwd [无用],角色)的帖子 我正在其中一个应用程序上实现SpringSecurity以从其功能中受益(会话中的权限,其类提供的方法等) 因此,我需要开发一个 自定义过滤器 -我猜想-能够从请求中检索用户信息,通过自定义 DetailsUserSe

  • 我正在尝试配置laravel的auth以适合我的db。但无论我做什么,都会覆盖像或在LoginController中,它忽略所有内容。有人知道如何用不同的数据库参数化laravel的身份吗? 以下是我在LoginController中更改的内容: 在用户模型中: 编辑:config/auth.php: ]; LoginController: 名称空间App\Http\Controllers\Aut

  • 我正在尝试在反应式Spring Boot应用程序中配置Spring Security性,并包括依赖于新的Spring Security版本5.0.0的父项目。RC1: 我将我的Spring WebSecurity配置为使用自定义AuthenticationFilter来检索我的身份验证信息,以及使用我自己的提供者的自定义AuthenticationManager。 配置: ReactiveAuth

  • 这是关于Flutter Firebase认证插件。< br >我试图在创建新用户后发送验证电子邮件,但sendEmailVerification()在内部使用currentUser()。这在我看来像是一个bug,但为了以防万一,我向stackoverflow提出了一个问题。错误在Android和IOS上是一样的。< br > 前两行返回Firebase User。第三个返回null。第四,如果第三

  • 如何检索当前登录用户的所有字段? 我看了很多教程和问题,其中一些是关于整个系列的,另一些是关于类似主题的,但没有找到相关信息。 非常感谢。 更新 当前代码: 控制台错误 之所以给出这个错误,是因为稍后我需要访问应该在该函数中填充的userName var

  • 我正在研究使用JWT身份验证的Spring Security实现。我不确定如何检查用户角色并在方法级别获得经过身份验证的用户。我在网上看到这个例子: 我需要从JWT令牌中提取用户类型吗?还有其他方法可以实现吗?在我看来,仅使用是不完整的。 看起来这段代码是用来获得用户如果使用会话类型,我得到NPE。你知道对于JWT我如何才能成为用户吗? Github完整来源:https://Github.com/