Spring 的 UserDetailsService
Spring's UserDetailsService
我正在尝试在我的 Spring 引导应用程序中配置 Spring 安全性,以仅允许某些用户访问某些 URL,如果他们具有特定角色,即用户或我在创建用户时存储的管理员角色。我看过几个示例 here,它们几乎可以满足我的需求。我对 Spring 的 UserDetailsService
界面以及在尝试访问 URL 时如何将用户名从用户传递给 UserDetailsService
有点困惑 localhost:8080/addtour
。目前我的代码如下所示:
@Data
@Scope("session")
public class User {
@Id
private String id;
private String userName;
private String password;
private List<Role> roles;
我的SecurityConfig
class:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.exceptionHandling()
.accessDeniedPage("/accessdenied")
.and()
.authorizeRequests()
.antMatchers("/resources/**", "/signup", "/search").permitAll()
.antMatchers("/viewtour").hasAnyRole("USER", "ADMIN")
.antMatchers("/addtour").hasAnyRole("ADMIN")
.and()
.logout()
.permitAll()
.logoutSuccessUrl("/index.html");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(new UserDetailServiceImpl());
}
实现Spring的UserDetailServiceImpl
UserDetailService
:
public class UserDetailServiceImpl implements UserDetailsService {
@Autowired
private UserService userService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
try {
User user = userService.retrieveUserByUserName(username);
if (user == null) {
return null;
}
return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getPassword(), getAuthorities(user));
} catch (Exception e){
throw new UsernameNotFoundException("User not found");
}
}
private Set<GrantedAuthority> getAuthorities(User user){
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
for (Role role : user.getRoles()) {
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role.toString());
authorities.add(grantedAuthority);
}
System.out.println("user authorities are " + authorities.toString());
return authorities;
}
我使用 Thymeleaf 的登录页面:
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="css/style.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" />
</head>
<body>
<div>
<div class="content">
<form action="#" th:action="@{/login}" th:object="${user}" method="post">
<div class="panel panel-default">
<br />
<h1 class="panel-title header-tab">
Login or <a href="/signup.html">Sign Up Here</a>
</h1>
<br />
<div class="panel-body">
<div class="form-group">
<label for="inputEmail" class="control-label col-xs-5">Username
or Email</label>
<div class="col-xs-7">
<input type="text" class="form-control" id="inputUsername" th:field="*{userName}" placeholder="Username or Email" />
</div>
</div>
<br/><br/>
<div class="form-group">
<label for="inputPassword" class="control-label col-xs-5">Password</label>
<div class="col-xs-7">
<input type="password" class="form-control" id="inputPassword" th:field="*{password}" placeholder="Password" />
</div>
</div>
<div class="form-group">
<div class="col-xs-offset-5 col-xs-10">
<div class="checkbox">
<label><input type="checkbox" />Remember Me</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-xs-offset-5 col-xs-7 btn-lg">
<input type="submit" value="Sign In" class="btn btn-primary btn-block"/>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</body>
</html>
您登录页面的参数名称有误,参见
FormLoginConfigurer#usernameParameter
:
The HTTP parameter to look for the username when performing authentication. Default is "username".
FormLoginConfigurer#passwordParameter
:
The HTTP parameter to look for the password when performing authentication. Default is "password".
更改登录页面中的参数名称或更改 SecurityConfig
中的名称。
我正在尝试在我的 Spring 引导应用程序中配置 Spring 安全性,以仅允许某些用户访问某些 URL,如果他们具有特定角色,即用户或我在创建用户时存储的管理员角色。我看过几个示例 here,它们几乎可以满足我的需求。我对 Spring 的 UserDetailsService
界面以及在尝试访问 URL 时如何将用户名从用户传递给 UserDetailsService
有点困惑 localhost:8080/addtour
。目前我的代码如下所示:
@Data
@Scope("session")
public class User {
@Id
private String id;
private String userName;
private String password;
private List<Role> roles;
我的SecurityConfig
class:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.exceptionHandling()
.accessDeniedPage("/accessdenied")
.and()
.authorizeRequests()
.antMatchers("/resources/**", "/signup", "/search").permitAll()
.antMatchers("/viewtour").hasAnyRole("USER", "ADMIN")
.antMatchers("/addtour").hasAnyRole("ADMIN")
.and()
.logout()
.permitAll()
.logoutSuccessUrl("/index.html");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(new UserDetailServiceImpl());
}
实现Spring的UserDetailServiceImpl
UserDetailService
:
public class UserDetailServiceImpl implements UserDetailsService {
@Autowired
private UserService userService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
try {
User user = userService.retrieveUserByUserName(username);
if (user == null) {
return null;
}
return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getPassword(), getAuthorities(user));
} catch (Exception e){
throw new UsernameNotFoundException("User not found");
}
}
private Set<GrantedAuthority> getAuthorities(User user){
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
for (Role role : user.getRoles()) {
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role.toString());
authorities.add(grantedAuthority);
}
System.out.println("user authorities are " + authorities.toString());
return authorities;
}
我使用 Thymeleaf 的登录页面:
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="css/style.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" />
</head>
<body>
<div>
<div class="content">
<form action="#" th:action="@{/login}" th:object="${user}" method="post">
<div class="panel panel-default">
<br />
<h1 class="panel-title header-tab">
Login or <a href="/signup.html">Sign Up Here</a>
</h1>
<br />
<div class="panel-body">
<div class="form-group">
<label for="inputEmail" class="control-label col-xs-5">Username
or Email</label>
<div class="col-xs-7">
<input type="text" class="form-control" id="inputUsername" th:field="*{userName}" placeholder="Username or Email" />
</div>
</div>
<br/><br/>
<div class="form-group">
<label for="inputPassword" class="control-label col-xs-5">Password</label>
<div class="col-xs-7">
<input type="password" class="form-control" id="inputPassword" th:field="*{password}" placeholder="Password" />
</div>
</div>
<div class="form-group">
<div class="col-xs-offset-5 col-xs-10">
<div class="checkbox">
<label><input type="checkbox" />Remember Me</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-xs-offset-5 col-xs-7 btn-lg">
<input type="submit" value="Sign In" class="btn btn-primary btn-block"/>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</body>
</html>
您登录页面的参数名称有误,参见
FormLoginConfigurer#usernameParameter
:The HTTP parameter to look for the username when performing authentication. Default is "username".
FormLoginConfigurer#passwordParameter
:The HTTP parameter to look for the password when performing authentication. Default is "password".
更改登录页面中的参数名称或更改 SecurityConfig
中的名称。