一个应用程序当前使用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);
}
}
答案 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的章节来源列表,但您只需查看列表中的最后一个。