我可以通过自定义方法验证用户吗?

时间:2015-08-12 23:29:30

标签: java spring spring-mvc spring-security

一个应用程序当前使用spring security和一个简单的用户名和密码,该登录表单由spring自动生成。用户名是有效的电子邮件地址。

我还有其他代码,可以在网址中向用户发送包含会话ID的电子邮件,以验证电子邮件地址。并且还向用户发送带有自定义PIN码的文本消息以验证其电话号码。注册站点,验证电子邮件和验证电话号码的步骤需要多种控制器方法和步骤。

是否有一种快速简便的方法可以将代码添加到现有的控制器方法中,该方法只是将用户声明为已登录?这将使用现有的spring安全配置,只需通过声明用户进行扩充即可登录。

例如,在控制器方法中:

//confirmed email
//confirmed phone number
//confirmed password
loggedin = true;

澄清:

确认文本密码和确认电子邮件需要在用户登录时每次发送和验证。如果无法使用简单的程序化声明记录某人,我至少可以用简单的程序化语句改变用户的角色?因此,他们使用用户名和密码登录到有限的条件状态,并且他们被分配了#34; StepOneRole"。然后他们验证发送给他们的密码,然后他们得到" StepTwoRole"。然后,他们验证发送给他们的电子邮件链接,并将他们的角色更改为" FullUser",他们可以在其中实际使用网站的安全部分。

我试图避免添加不必要的复杂性,但用户需要每次验证n个因子

另请注意,我的SecurityConfig.java如下所示,并使用UserDetailService,其中一个答案中提到了这一点:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private UserDetailsService userDetailsService;

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .csrf().disable()
        .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/user-home")
            .usernameParameter("j_username")
            .passwordParameter("j_password")
            .loginProcessingUrl("/j_spring_security_check")
            .failureUrl("/login")
            .permitAll()
            .and()
        .logout()
            .logoutUrl("/logout")
            .logoutSuccessUrl("/login")
            .and()
        .authorizeRequests()
            .antMatchers("/user-home").hasAuthority("USER")
            .antMatchers("/j_spring_security_check").permitAll()
            .and()
        .userDetailsService(userDetailsService);

}

}

1 个答案:

答案 0 :(得分:3)

以下代码将以编程方式记录用户:

    Authentication authentication =
        new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
    SecurityContextHolder.getContext().setAuthentication(authentication);

请注意,user位于用户对象之上,实现UserDetails

同样,要将用户注销,可以使用以下代码:

SecurityContextHolder.getContext().setAuthentication(null);

回复您的评论

我不确定Spring安全性如何在没有用户类或实现UserDetails的映射类的情况下使用您的用户和角色。在我的一个项目中,我有一个这样的映射类:

public class UserDetailsImpl implements UserDetails {


    private static final long serialVersionUID = 5197941260523577515L;

    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public UserDetailsImpl(User user) {
        this.user = user;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {

        Collection<GrantedAuthority> authorities = new HashSet<GrantedAuthority>(
                user.getRoles().size() + 1);

        for (Role role : user.getRoles())
            authorities.add(new SimpleGrantedAuthority("ROLE_" + role.name()));

        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));

        return authorities;

    }

    @Override
    public String getPassword() {
        return user.getPassword();
    }

    @Override
    public String getUsername() {
        return user.getEmail();
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }

}

所以,我从我的用户对象创建它的一个实例,并使用它以编程方式登录,如下所示:

UserDetailsImpl userDetails = new UserDetailsImpl(user);

Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);

对第三条评论的回应

是的,User是一个自编码类。 Here是包含整个项目源的zip的链接。这是a video tutorial的章节来源列表,但您只需查看列表中的最后一个。