我将我的应用程序配置为每个帐户只允许一个会话
当我使用JdbcDaoImpl提供程序时,它工作正常
当我将DaoAuthenticationProvider与自定义用户对象扩展弹簧用户一起使用时,它也可以正常工作。
但是当我尝试使用自定义用户对象实现 UsersDetails接口设置spring security时,当我尝试使用其他帐户登录时,我收到了上面的消息。我无法弄清楚原因。
这是我的安全配置:
def Game(x, y):
if __name__ == "__main__":
main()
turtle.onscreenclick(Game)
我的自定义用户对象:
<session-management invalid-session-url="/">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</session-management>
<authentication-manager>
<authentication-provider ref="daoAuthenticationProvider"/>
</authentication-manager>
<beans:bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsServiceImplementation"></beans:property>
</beans:bean>
<beans:bean id="userDetailsServiceImplementation" class="com.company.service.implementation.UserServiceImpl" />
这是我的UserDetailsService实现:
public class UserVo extends CommonVo implements UserDetails{
private String username;
private String password;
private String firstName;
private String lastName;
private String enabled;
private List<GrantedAuthority> userAuthorities;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEnabled() {
return enabled;
}
public void setEnabled(String enabled) {
this.enabled = enabled;
}
public List<GrantedAuthority> getUserAuthorities() {
return userAuthorities;
}
public void setUserAuthorities(List<GrantedAuthority> userAuthorities) {
this.userAuthorities = userAuthorities;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return userAuthorities;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return "Y".equals(enabled) ? true : false;
}
}
如果我返回扩展spring User类的对象,在这种情况下是LoginVo。
,这可以正常工作答案 0 :(得分:0)
对于并发控制,Spring Security使用SessionRegistry
default implementation使用HashMap
来存储内容。要使HashMap
正常工作,您需要使用正确实施的hashCode
和equals
方法。如果您没有(或始终返回默认值),它将无法正常工作。
要解决,只需在自定义对象中实施正确的hashCode
和equals
方法。
答案 1 :(得分:0)
好的,我已经通过在原始问题的评论部分中关注@ m-deinum回答来解决我的问题。
我所做的是通过右键单击eclipse生成hashCode()
和equals()
- &gt;来源 - &gt;在UserVo和CommonVo中生成hashCode()和equals()。
事实证明,如果我有自己的UsersDetail
接口实现
答案 2 :(得分:0)
如果有人在春季启动时遇到此问题,这是您必须在安全配置文件中添加的内容,除了M.Deinum Answer
//security configuration class for implementing spring security on urls
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService userDetailsService;
//for handling user success handler
@Autowired
private CustomizeAuthenticationSuccessHandler customizeAuthenticationSuccessHandler;
@Override
//this configuration is for handling user requests
protected void configure(HttpSecurity http) {
try {
http
.authorizeRequests()
.antMatchers("/orders").permitAll()
.antMatchers("/createrole").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/admin/**").hasAuthority("admin")
.antMatchers("/agent/**").hasAuthority("agent")
.antMatchers("/distributor/**").hasAuthority("distributor")
.antMatchers("/home/**").hasAuthority("user").anyRequest()
.authenticated().and().csrf().disable().formLogin().successHandler(customizeAuthenticationSuccessHandler)
.loginPage("/login").failureUrl("/login?error=true")
.usernameParameter("username")
.passwordParameter("password")
.and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/logout.done").deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
.logoutSuccessUrl("/login").and().exceptionHandling().accessDeniedPage("/403");
http.sessionManagement( ).maximumSessions(1). maxSessionsPreventsLogin(true);
http.sessionManagement( ).sessionFixation( ).migrateSession( )
.sessionAuthenticationStrategy( registerSessionAuthStr( ) );
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("Exception here");
}
}
//this method allows static resources to be neglected by spring security
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**","/assets/**","/fonts/**","/dis/**","/vendor1/**","/mobile/**");
}
@Bean
public SessionRegistry sessionRegistry( ) {
SessionRegistry sessionRegistry = new SessionRegistryImpl( );
return sessionRegistry;
}
@Bean
public RegisterSessionAuthenticationStrategy registerSessionAuthStr( ) {
return new RegisterSessionAuthenticationStrategy( sessionRegistry( ) );
}
///Very important ,you wont login again after logout if you dont include this
@Bean
public ServletListenerRegistrationBean<HttpSessionEventPublisher> httpSessionEventPublisher() {
return new ServletListenerRegistrationBean<HttpSessionEventPublisher>(new HttpSessionEventPublisher());
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
//BCryptPasswordEncoder encoder = passwordEncoder();
try {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
} catch (Exception e) {
System.out.println("Login Failed");
}
}
}
答案 3 :(得分:0)
我正在开发没有任何启动配置的普通spring应用程序[Configure without xml] ...
我在客户中覆盖了我的hascode和equal方法。
5次或10次尝试获得味精后,我无法登录。[超过此主体的最大会话数为1]
我没有这种方法,如何在普通应用程序中实现。
@Bean
public ServletListenerRegistrationBean<HttpSessionEventPublisher> httpSessionEventPublisher() {
return new ServletListenerRegistrationBean<HttpSessionEventPublisher>(new HttpSessionEventPublisher());
}
在控制台中-
会话被破坏- 会话是新建的- 会话被破坏- 会话是新建的- 会话被破坏- 会话是新创建的 会话是新建的---- 信息匿名用户..................