java-Spring记住我,带有额外的登录参数
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java-Spring记住我,带有额外的登录参数,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含7711字,纯文字阅读大概需要12分钟。
内容图文
![java-Spring记住我,带有额外的登录参数](/upload/InfoBanner/zyjiaocheng/695/045346cad4f34615bb648398ed52b2d7.jpg)
在spring mvc应用程序中,我在登录屏幕上捕获了一个附加的“位置”参数,除了用户名外,还将其用于身份验证.所以在“ loadUserByUsername”中,我的sql查询是这样的,
select from user where username = ? and location = ?
现在,如果用户是我的“记住我”用户,则因为没有登录提示,所以无法捕获“位置”参数.如果使用“记住我”功能,spring只会在Cookie中存储用户名.对于“记住我”登录,它随后从cookie中检索该用户名,并将其传递给“ loadUserByUsername”调用,以从数据库加载用户.因此,就我而言,对于记住我的用户,由于“位置”为空,加载用户的查询失败.
我想知道是否有一种方法可以覆盖默认的弹簧行为,并将“位置”和用户名一起存储在Cookie中,然后将位置和用户名传递给PersistentTokenBasedRememberMeServices.processAutoLoginCookie()中的“ loadUserByUsername”.
请参阅下面的代码以供参考,
CustomAuthenticationFilter.java:-
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
final Long locationId = Long.parseLong(request.getParameter("locations"));
request.getSession().setAttribute("LOCATION_ID", locationId);
return super.attemptAuthentication(request, response);
}
}
SecurityConfig.java:-
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;
@Autowired
private AuthenticationManagerBuilder auth;
@Autowired
public void configureGlobal(UserDetailsService userDetailsService, AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Autowired
AccessDeniedExceptionHandler accessDeniedExceptionHandler;
@Bean
public CustomInvalidSessionStrategy invalidSessionStrategy() {
return new CustomInvalidSessionStrategy();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.antMatchers("/error/**").permitAll()
.antMatchers("/secured/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
// .defaultSuccessUrl("/")
.permitAll()
.and().rememberMe().rememberMeServices(persistentTokenBasedRememberMeServices())
.and()
.logout()
.permitAll()
.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedExceptionHandler);
http.addFilterBefore(customAuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class);
http.addFilterAfter(rememberMeAuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() {
AuthenticationManager manager = null;
try {
manager = super.authenticationManagerBean();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return manager;
}
@Bean
public SimpleUrlAuthenticationSuccessHandler simpleUrlAuthenticationSuccessHandler() {
SimpleUrlAuthenticationSuccessHandler handler = new SimpleUrlAuthenticationSuccessHandler();
handler.setDefaultTargetUrl("/");
return handler;
}
@Bean
public SimpleUrlAuthenticationFailureHandler simpleUrlAuthenticationFailureHandler() {
SimpleUrlAuthenticationFailureHandler handler = new SimpleUrlAuthenticationFailureHandler();
handler.setDefaultFailureUrl("/login?error");
return handler;
}
@Bean
public CustomAuthenticationFilter customAuthenticationFilter () {
CustomAuthenticationFilter filter= new CustomAuthenticationFilter();
filter.setRequiresAuthenticationRequestMatcher(
new AntPathRequestMatcher("/login","POST"));
filter.setAuthenticationManager(authenticationManagerBean());
filter.setUsernameParameter("username");
filter.setPasswordParameter("password");
filter.setAuthenticationSuccessHandler(simpleUrlAuthenticationSuccessHandler());
filter.setAuthenticationFailureHandler(simpleUrlAuthenticationFailureHandler());
filter.setRememberMeServices(persistentTokenBasedRememberMeServices());
return filter;
}
@Bean
public RememberMeAuthenticationFilter rememberMeAuthenticationFilter() {
RememberMeAuthenticationFilter filter = new RememberMeAuthenticationFilter();
filter.setAuthenticationManager(authenticationManagerBean());
filter.setRememberMeServices(persistentTokenBasedRememberMeServices());
return filter;
}
@Bean
public PersistentTokenBasedRememberMeServices persistentTokenBasedRememberMeServices() {
PersistentTokenBasedRememberMeServices service = new PersistentTokenBasedRememberMeServices("remember_me_key", userDetailsService, persistentTokenRepository());
service.setCookieName("remember_me");
service.setTokenValiditySeconds(864000);
return service;
}
@Autowired
public UserDetailsService userDetailsService;
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl tokenRepositoryImpl = new JdbcTokenRepositoryImpl();
tokenRepositoryImpl.setDataSource(dataSource);
return tokenRepositoryImpl;
}
}
解决方法:
如果您想覆盖默认的spring行为并将额外的参数存储在cookie中,则应实现Spring的UserDetails接口.有一个例子
package example.userdetails;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
public class CustomUserDetails implements UserDetails {
private long id;
private String firstName;
private String lastName;
private String login;
private String password;
private boolean isAccountNonExpired;
private boolean isAccountNonLocked;
private boolean isCredentialsNonExpired;
private boolean isEnabled;
private Collection<? extends GrantedAuthority> authorities;
public CustomUserDetails(long id, String firstName, String lastName, String login, String password, boolean isEnabled, Collection<? extends GrantedAuthority> authorities) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.login = login;
this.password = password;
this.authorities = authorities;
this.isEnabled = isEnabled;
this.isCredentialsNonExpired = true;
this.isAccountNonLocked = true;
this.isAccountNonExpired = true;
}
public long getId() {
return id;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return login;
}
@Override
public boolean isAccountNonExpired() {
return isAccountNonExpired;
}
@Override
public boolean isAccountNonLocked() {
return isAccountNonLocked;
}
@Override
public boolean isCredentialsNonExpired() {
return isCredentialsNonExpired;
}
@Override
public boolean isEnabled() {
return isEnabled;
}
public boolean hasRole(String role) {
for (GrantedAuthority grantedAuthority : authorities) {
if (grantedAuthority.getAuthority().equals(role)) {
return true;
}
}
return false;
}
}
要获取登录用户,您可以使用
CustomUserDetails userDetails = (CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
对于使用loadUserByUsername,您应该实现接口UserDetailsS??ervice.例如
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserDAO userDAO;
@Override
@Transactional
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
User user = userDAO.getUserByLogin(userName);
if (user == null) {
throw new UsernameNotFoundException("Wrong login");
}
List<GrantedAuthority> authorities = buildUserAuthority(user.getRoles());
return new CustomUserDetails(user.getUserId(), user.getFirstName(), user.getLastName(), user.getLogin(), user.getPassword(), authorities);
}
private List<GrantedAuthority> buildUserAuthority(Set<Role> roles) {
Set<GrantedAuthority> authoritySet = roles.stream().map(role -> new SimpleGrantedAuthority(buildRoleForAuthorization(role.getRole()))).collect(Collectors.toSet());
return new ArrayList<>(authoritySet);
}
}
内容总结
以上是互联网集市为您收集整理的java-Spring记住我,带有额外的登录参数全部内容,希望文章能够帮你解决java-Spring记住我,带有额外的登录参数所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。