无法使用 Spring 安全登录 - 使用外部数据库的基于注释的配置
Posted
技术标签:
【中文标题】无法使用 Spring 安全登录 - 使用外部数据库的基于注释的配置【英文标题】:Unable to login with Spring security -Annotation based configuration with external database 【发布时间】:2016-08-01 04:57:15 【问题描述】:我正在按照这些 1 2 链接配置 Spring Security。我的问题是 Spring Security 的默认登录页面没有在我的应用程序中呈现,即我能够点击所有 url。我错过了什么下面是我的配置。
WebSecurityConfigurerAdapter
Implementaion-
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
@Autowired
private DataSource dataSource;
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder registry) throws Exception
registry.userDetailsService(customUserDetailsService);
@Override
public void configure(WebSecurity web) throws Exception
web.ignoring().antMatchers("/resources/**");
@Override
protected void configure(HttpSecurity http) throws Exception
http.csrf().disable()
.authorizeRequests()
.antMatchers("/login","/login/form**","/register","/logout").permitAll()
.antMatchers("/admin","/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login/form")
.loginProcessingUrl("/login")
.failureUrl("/login/form?error")
.permitAll();
UserDetailsService
实现
@Component
public class CustomUserDetailsService implements UserDetailsService
@Autowired
private UserService userService;
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException
User user = userService.findUserByEmail(userName);
if(user == null)
throw new UsernameNotFoundException("UserName "+userName+" not found");
return new SecurityUser(user);
User
实现-
public class SecurityUser extends User implements UserDetails
private static final long serialVersionUID = 1L;
public SecurityUser(User user)
if(user != null)
this.setId(user.getId());
this.setName(user.getName());
this.setEmail(user.getEmail());
this.setPassword(user.getPassword());
this.setDob(user.getDob());
this.setRoles(user.getRoles());
@Override
public Collection<? extends GrantedAuthority> getAuthorities()
Collection<GrantedAuthority> authorities = new ArrayList<>();
List<Role> userRoles = this.getRoles();
if(userRoles != null)
for (Role role : userRoles)
SimpleGrantedAuthority authority = new SimpleGrantedAuthority(role.getRoleName());
authorities.add(authority);
return authorities;
@Override
public String getPassword()
return super.getPassword();
@Override
public String getUsername()
return super.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;
我的SpringWebAppInitializer
班级是-
public class SpringWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
@Override
protected Class<?>[] getServletConfigClasses()
return new Class<?>[] AppConfig.class ;
@Override
protected String[] getServletMappings()
return new String[] "/" ;
@Override
protected Class<?>[] getRootConfigClasses()
return new Class<?>[] AppConfig.class;
@Override
protected Filter[] getServletFilters()
return new Filter[]
new DelegatingFilterProxy("springSecurityFilterChain"),
new OpenEntityManagerInViewFilter();
此外,我尝试使用我的自定义登录页面,即使这也没有渲染-
<form:form id="loginForm" method="post" action="$appUrl/controller/login"
modelAttribute="user" class="register" role="form">
<div class="form-group">
<div class="">
<input type="text" id="username" name="username"
class="form-control register-input" placeholder="UserName" />
</div>
</div>
<div class="form-group">
<div class="">
<input type="password" id="password" name="password"
class="form-control register-input" placeholder="Password" />
</div>
</div>
<input type="hidden" name="$_csrf.parameterName" value="$_csrf.token" />
<div class="form-group">
<div class="col-sm-offset-3">
<input type="submit" class="btn btn-primary" value="Login">
</div>
</div>
</form:form>
【问题讨论】:
【参考方案1】:如果你想使用默认的spring登录页面,你不要放:
.formLogin()
.loginPage("/login/form") <--- this line is not needed for default spring login
.loginProcessingUrl("/login")
.failureUrl("/login/form?error")
.permitAll(); <--- and this no need too
根据您上面的配置,您正在使用自己的登录页面。 另一件事是您的表单登录。
请注意如果您使用标签form
,您也需要在输入时使用它。
例子:
<form:form modelAttribute="foo" method="post" ...
<form:input type="text" id="username" path="username" ....
通过使用标签form
,您需要包含modelAttribute=""
并在控制器中将其调用为@ModelAttribute("foo") Users users
,您应该注意到标签form
在<input>
中没有使用name
,而是它们是使用path
。
但是,您也可以使用不带标签form
的普通形式,如果您使用它,则无需包含modelAttribute=""
并将其用作普通形式。
如果你的 spring security 没有触发或者你仍然可以点击任何地方,那是因为SpringWebAppInitializer
没有加载你的安全配置并且它不知道配置是否存在。我建议你查找WebApplicationInitializer
。
【讨论】:
以上是关于无法使用 Spring 安全登录 - 使用外部数据库的基于注释的配置的主要内容,如果未能解决你的问题,请参考以下文章
Keycloak - spring boot - 外部登录网页
无法使用 Angular 2 作为前端并使用基本 Http 身份验证获取有关 Spring 安全性的登录详细信息
如何解决在使用 Spring Boot 和 Spring Security 启用 CSRF 后无法正常工作的登录问题?