#java #spring #spring-security
#java #spring #spring-безопасность
Вопрос:
Я пытаюсь завершить систему входа в систему, но когда я вхожу в систему, я получаю следующую ошибку
- «Ошибка HTTP 404 НЕ МОЖЕТ БЫТЬ НАЙДЕНА»http://localhost:8181/user_login «
Я знаю, что это, очевидно, означает, что его невозможно найти, но я не понимаю, почему он не может его найти. Вот моя конфигурация безопасности
@EnableWebSecurity
@Configuration
@Order(2)
public class UserSecurityConfig extends WebSecurityConfigurerAdapter {
protected void user(HttpSecurity http) throws Exception {
http.authorizeRequests()
.and()
.formLogin()
.loginPage("/user_login")
.defaultSuccessUrl("/success")
.failureUrl("/login?error==true")
.permitAll()
.and()
.csrf()
.disable()
;
}
@Bean
public UserDetailsService userDetailsService() {
return new CustomUserDetailsService();
}
@Autowired
public void configurationGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
И форма входа в систему
<form:form name='user' action="/user_login" method='POST'>
<form:errors path="username" />
<label for="username">Email address</label>
<input type='text' class="form-control" name='username' value='' placeholder="Enter Email address"></td>
<label for="password">Password: </label>
<input type='password' class="form-control" name='password' /></td>
<input name="submit" class="btn btn-primary" type="submit" value="submit" /></td>
</form:form>
Вот моя другая защита для администратора, которая работает
@EnableWebSecurity
@Configuration
@Order(1)
public class AdminSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password("12345").roles("ADMIN")
.and()
.withUser("tester").password("56789").roles("ADMIN");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/login")
.permitAll()
.antMatchers("/newUser")
.permitAll()
.antMatchers("/admin")
.hasAnyRole("ADMIN")
.and()
.formLogin()
.loginPage("/login1")
.defaultSuccessUrl("/admin")
.failureUrl("/login?error=true")
.permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/")
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
.and()
.csrf()
.disable()
;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Если у кого-нибудь есть какие-либо идеи или советы по решению этой проблемы, я был бы очень благодарен. Спасибо, Джим
Ответ №1:
Основная проблема заключается в неправильном способе определения конфигурации spring-security, когда вы используете WebSecurityConfigurerAdapter
, вы должны использовать переопределения методов для определения пользовательских настроек, потому что spring не знает, как найти этот метод:
protected void user(HttpSecurity http) throws Exception {
http.authorizeRequests()
.and()
.formLogin()
.loginPage("/user_login")
.defaultSuccessUrl("/success")
.failureUrl("/login?error==true")
.permitAll()
.and()
.csrf()
.disable()
;
}
Ц Рабочая версияЖ
@Configuration
@EnableWebSecurity
public class UserSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.and()
.formLogin()
.loginPage("/user_login")
.defaultSuccessUrl("/success")
.failureUrl("/login?error==true")
.permitAll()
.and()
.csrf().disable();
}
@Bean
public UserDetailsService userDetailsService() {
return new CustomUserDetailsService();
}
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService())
.passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Объединенная версия:
Я использую spring-security 5.4.2
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/newUser").permitAll()
.antMatchers("/admin").hasAnyRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.failureUrl("/login?error==true")
.successHandler((httpServletRequest, httpServletResponse, authentication) -> {
Set<String> roles = AuthorityUtils.authorityListToSet(authentication.getAuthorities());
if (roles.contains("ROLE_ADMIN")) {
httpServletResponse.sendRedirect("/admin");
} else {
httpServletResponse.sendRedirect("/success");
}
})
.permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/")
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
.and()
.csrf().disable();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("{noop}password").roles("USER")
.and()
.withUser("admin").password("{noop}12345").roles("ADMIN")
.and()
.withUser("tester").password("{noop}56789").roles("ADMIN");
}
}
Я тестировал возможности входа в систему, и все работает, конечно, мы не можем поддерживать два разных defaultSuccessUrl
, потому что http mapping( HttpSecurity
) является единственным экземпляром, и какая конфигурация будет загружена первой, она defaultSuccessUrl
будет использоваться для формы входа.
Я опускаю loginPage
config, и я не думаю, что мы можем поддерживать обе страницы входа, такие же, как для defaultSuccessUrl
config.
Комментарии:
1. Спасибо за ваш ответ, боюсь, это все еще не работает. У меня есть порядок, так как у меня есть @Order(1) для моего входа в систему администратора, который работает нормально. Я добавлю это к вопросу, чтобы избежать путаницы. У вас есть какие-либо другие идеи о том, что я могу сделать, чтобы это исправить?
2. Я думаю, вам следует объединить две конфигурации безопасности в один класс, потому что я ожидаю столкновения двух
WebSecurityConfigurerAdapter
типизированных классов3. Я обновил ответ, пожалуйста, проверьте общую конфигурацию, она вам подходит?
4. Спасибо за вашу помощь, ответ работает отлично
5. Я рад, что это получилось!