#spring #spring-mvc #spring-security
#spring #spring-mvc #spring-security
Вопрос:
Я создал двух пользователей с ролями АДМИНИСТРАТОРА и ПОЛЬЗОВАТЕЛЯ, но каждый раз, когда я пытаюсь войти в систему, сервер возвращает 403.
WebSecurityConfig:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/admin/**")
.access("hasAnyAuthority('ADMIN','USER')")
.and().formLogin().loginPage("/login").failureUrl("/login?error")
.usernameParameter("username")
.passwordParameter("password")
.and().logout().logoutSuccessUrl("/login?logout")
.and().csrf().disable();
}
мой пользовательский сервис, который отображает моих пользователей из базы данных:
@Transactional(readOnly = true)
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userDao.findByUserName(username);
org.springframework.security.core.userdetails.User.UserBuilder builder = null;
if (user != null) {
builder = org.springframework.security.core.userdetails.User.withUsername(username);
builder.disabled(!user.isEnabled());
builder.password(user.getPassword());
String[] authorities = user.getUserRole()
.stream().map(a -> a.getRole()).toArray(String[]::new);
builder.authorities(authorities);
} else {
throw new UsernameNotFoundException("User not found.");
}
return builder.build();
}
csrf отключен. Я также использую метод hasAnyUthority *, поэтому мне не нужен префикс ROLE__.
Я использую spring security 5
Мой login.html
<head>
<meta charset="utf-8"/>
<link rel="stylesheet" type="text/css" href="resources/style.css"/>
</head>
<body>
<div class="container">
<header>
<h1>Login</h1>
</header>
<div class="alert alert-error" th:if="${error != null}">
<div>
<strong>Okay, Houston, we've had a problem here.</strong>
</div>
</div>
<div class="alert alert-error" th:if="${logout != null}">
<div>
<strong>Okay, Houston, you're logged out successfully .</strong>
</div>
</div>
<form class="form-horizontal" th:action="@{/login}" method="POST">
<fieldset>
<div class="control-group">
<label class="control-label">Login</label>
<div class="controls">
<div class="input-prepend">
<span class="add-on">@</span>
<input id="loginField" name="username" class="span3" type="text"/>
</div>
</div>
</div>
<div class="control-group">
<label class="control-label">Password</label>
<div class="controls">
<input id="passwordField" name="password" class="span3" type="password"/>
</div>
</div>
<div class="form-actions">
<button id="loginButton" class="btn btn-primary" type="submit">Login</button>
</div>
</fieldset>
</form>
</div>
</body>
Я сделал все, как в примерах проектов, но он по-прежнему не хочет регистрировать меня.
Комментарии:
1. Покажите ваш запрос на вход с заголовком и телом.
Ответ №1:
Я не вижу, чтобы это hasAnyAuthority(...)
работало без «ROLE_», попробуйте .access("hasAnyRole('ADMIN','USER')")
или .access("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
.
Обратите внимание, что в String[] authorities = user.getUserRole().stream().map(a -> a.getRole()).toArray(String[]::new);
вам нужно a.getRole()
возвращать с префиксом ROLE_
или тем же, что у вас будет в hasAnyAuthority(...)
Например, если ваш a.getRole()
вернет WHAT_EVER
то hasAnyAuthority('WHAT_EVER)
должно сработать, но hasAnyRole('WHAT_EVER')
будет ожидать, что a.getRole()
вернет ROLE_WHAT_EVER
Комментарии:
1. У меня есть администратор с ролью ‘ADMIN’, и я использую hasAnyAuthority. И это не работает. Я знаю, что для hasanyrole_ требуется ROLE_ADMIN. Вот почему я использую hasAnyAuthority
Ответ №2:
Возможно, это кому-то поможет, поэтому я не отвечу на свой вопрос. Я не смог войти в систему, потому что при запуске моей программы я добавляю несколько новых пользователей с незашифрованным паролем. Но spring security все равно расшифровывает его, поэтому я не смог войти в систему и получил 403 повторных запроса. Все, что мне нужно, это зашифровать пароль перед добавлением его в базу данных.