这篇文章同样是使用的Java配置,而非XML配置,如果你对于Java配置的Spring MVC开发还不太熟悉,可以先看我这篇文章。
转自:http://xueliang.org/article/detail/20170302232815082
Authority
创建一个 Authority
,实现自 org.springframework.security.core.GrantedAuthority
类,getAuthority
方法只返回一个表示权限名称的字符串,如 AUTH_USER
、 AUTH_ADMIN
、 AUTH_DBA
等。
public class Authority implements GrantedAuthority { private static final long serialVersionUID = 1L; private String authority; public Authority() { } public Authority(String authority) { this.setAuthority(authority); } @Override public String getAuthority() { return this.authority; } public void setAuthority(String authority) { this.authority = authority; } }
User
User
类实现自 org.springframework.security.core.userdetails.UserDetails
接口,包含一组权限的集合 authorities
。
public class User implements UserDetails { private static final long serialVersionUID = 1L; private String username; private String password; private List<Authority> authorities; @Override public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } @Override public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { return this.authorities; } public void setAuthorities(List<Authority> authorities) { this.authorities = authorities; } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } }
UserDetailsService
MyUserDetailsService
实现了 org.springframework.security.core.userdetails.UserDetailsService
的 loadUserByUsername
方法,该方法根据用户名查询符合条件的用户,若没有找到符合条件的用户,必须抛出 UsernameNotFoundException
异常,而不能返回空。这里可以调用 DAO 层,从数据库查询用户,我为了简单,直接将用户临时放到一个常量内,模拟从数据库查询用户。
@Service public class MyUserDetailsService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { List<User> userList = Constants.userList; for (int i = 0, len = userList.size(); i < len; i++) { User user = userList.get(i); if (user.getUsername().equals(username)) { return user; } } throw new UsernameNotFoundException("用户不存在!"); } }
SecurityConfig
SecurityConfig
类继承org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
,WebSecurityConfigurerAdapter
提供了一些默认的配置,方便创建一个实例。
进入 configure
方法中,首先允许任何情况下的对csrfTokenApi
的请求,该 API 返回一个 csrfToken
,默认情况下除GET
、HEAD
、TRACE
和 OPTIONS
外,所有请求都必须经过 CSRF 认证。接下来对不同的API请求设置不同的权限,并且确保所有对/api/
下的请求都经过了认证。
这里向 access
方法传递的表达式中的权限名称,对应上面提到的 Authority
类中 getAuthority
返回的字符串的值,详细的表达式介绍,请移步至这里。
接着,对登录表单进行配置。通过 loginProcessingUrl
配置表单提交地址,这个地址对应的API不需要自己写,Spring Security 会自动拦截提交到此地址请求,将其视为登录请求。如果希望登录成功后通过服务器转发到其他页面,可以调用 successForwardUrl(String forwardUrl)
方法指定跳转的地址,对应地,指定失败后跳转地址的方法是 failureForwardUrl(