sprring Security和shiro都是当前最流行的两个认真框架,一直都没有去学习,这段时间疫情的影响,一直在家办公,晚上的时候找时间学习了一下,spring Security,而且shiro的学习也是比较模糊,都没完整的了解过整个流程,接下来的一段时间先进行一下了解,出一系列的笔记.跟多配置参考:https://github.com/wuyouzhuguli/SpringAll ,github上发现的项目,初学者十分的实用
配置流程
- 引入pom依赖
- 创建user实体
- 配置userdetailservice,重写loaduserByUsername方法,用于数据库的查询用户的对象,获取权限等
- 配置登录成功和失败的handler
- 配置SecurityConfig
pom依赖
<parent>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-parent/<artifactid>
<version>1.5.14.RELEASE/<version>
<relativepath>
<dependencies>
<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-web/<artifactid>
<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-security/<artifactid>
user实体
user实体需要实现 UserDetails接口
<code>public class MyUser implements Serializable, UserDetails {/<code>
<code> private static final long serialVersionUID = 3497935890426858541L;/<code>
<code> /<code>
<code> private String username;/<code>
<code> /<code>
<code> private String password;/<code>
<code> /<code>
<code> private boolean accountNonExpired = true;/<code>
<code> /<code>
<code> private boolean accountNonLocked= true;/<code>
<code> /<code>
<code> private boolean credentialsNonExpired= true;/<code>
<code> /<code>
<code> private boolean enabled= true;/<code>
<code> @Override/<code>
<code> public String getUsername() {/<code>
<code> return username;/<code>
<code> }/<code>
<code> /<code>
<code> public void setUsername(String userName) {/<code>
<code> this.username = userName;/<code>
<code> }/<code>
<code> /<code>
<code> /****/<code>
<code> *实现userDetail的发方法/<code>
<code> *//<code>
<code> @Override/<code>
<code> public Collection extends GrantedAuthority> getAuthorities() {/<code>
<code> return null;/<code>
<code> }/<code>
<code> /<code>
<code> @Override/<code>
<code> public String getPassword() {/<code>
<code> return password;/<code>
<code> }/<code>
<code> @Override/<code>
<code> public boolean isAccountNonExpired() {/<code>
<code> }/<code>
<code> /<code>
<code> @Override/<code>
<code> public boolean isAccountNonLocked() {/<code>
<code> return accountNonLocked;/<code>
<code> }/<code>
<code> public void setAccountNonExpired(boolean accountNonExpired) {/<code>
<code> this.accountNonExpired = accountNonExpired;/<code>
<code> }/<code>
<code> /<code>
<code> @Override/<code>
<code> public boolean isAccountNonLocked() {/<code>
<code> return accountNonLocked;/<code>
<code> }/<code>
<code> public void setAccountNonLocked(boolean accountNonLocked) {/<code>
<code> this.accountNonLocked = accountNonLocked;/<code>
<code> }/<code>
<code> /<code>
<code> @Override/<code>
<code> public boolean isCredentialsNonExpired() {/<code>
<code> return credentialsNonExpired;/<code>
<code> }/<code>
<code> /<code>
<code> public void setCredentialsNonExpired(boolean credentialsNonExpired) {/<code>
<code> this.credentialsNonExpired = credentialsNonExpired;/<code>
<code> }/<code>
<code> /<code>
<code> @Override/<code>
<code> public boolean isEnabled() {/<code>
<code> return enabled;/<code>
<code> }/<code>
<code> /<code>
<code> public void setEnabled(boolean enabled) {/<code>
<code> this.enabled = enabled;/<code>
<code> }/<code>
<code>}/<code>
userdetailService
实现UserDetailsService接口,实现loaduseByUsername 方法输入mapper方法,通过用户名返回user对象,这里模拟查找到用户的情况, PasswordEncoder 配置密码的加密模式,
<code>@Configuration/<code>
<code>public class UserDetailService implements UserDetailsService {/<code>
<code> @Autowired/<code>
<code> private PasswordEncoder passwordEncoder;/<code>
<code> /<code>
<code> @Override/<code>
<code> public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {/<code>
<code> // 模拟一个用户,替代数据库获取逻辑/<code>
<code> MyUser user = new MyUser();/<code>
<code> user.setUsername(username);/<code>
<code> user.setPassword(this.passwordEncoder.encode("123456"));/<code>
<code> // 输出加密后的密码/<code>
<code> System.out.println(user.getPassword());/<code>
<code> /<code>
<code> return new User(username, user.getPassword(), user.isEnabled(),/<code>
<code> user.isAccountNonExpired(), user.isCredentialsNonExpired(),/<code>
<code> user.isAccountNonLocked(), AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));/<code>
<code> }/<code>
<code> }/<code>
失败handler和成功的hanlder
成功和失败的日志记录.跳转的页面等
登录成功的拦截器,实现接口AuthenticationSuccessHandler,重写方法,成功后跳转到index
<code>@Component/<code>
<code>public class MyAuthenticationSucessHandler implements AuthenticationSuccessHandler {/<code>
<code> /<code>
<code> /<code>
<code> private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();/<code>
<code> /<code>
<code> @Override/<code>
<code> public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,/<code>
<code> Authentication authentication) throws IOException {/<code>
<code> redirectStrategy.sendRedirect(request, response, "/index");/<code>
<code> }/<code>
<code>}/<code>
登录失败提示异常信息
@Component
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Autowired
private ObjectMapper mapper;
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException {
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(mapper.writeValueAsString(exception.getMessage()));
}
}
配置Securityconfig 最后一步,配置SecurityConfig
<code>@Configuration/<code>
<code>public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {/<code>
<code> //handler/<code>
<code> @Autowired/<code>
<code> private MyAuthenticationSucessHandler authenticationSuccessHandler;/<code>
<code> /<code>
<code> @Autowired/<code>
<code> private MyAuthenticationFailureHandler authenticationFailureHandler;/<code>
<code> /<code>
<code> /<code>
<code> @Override/<code>
<code> protected void configure(HttpSecurity http) throws Exception {/<code>
<code> http.formLogin() // 表单登录/<code>
<code> // http.httpBasic() // HTTP Basic/<code>
<code> .loginPage("/login.html") // 登录跳转 URL/<code>
<code> .loginProcessingUrl("/login") // 处理表单登录 URL/<code>
<code> .successHandler(authenticationSuccessHandler) // 处理登录成功/<code>
<code> .failureHandler(authenticationFailureHandler) // 处理登录失败/<code>
<code> .and()/<code>
<code> .authorizeRequests() // 授权配置/<code>
<code> .antMatchers("/authentication/require", "/login.html").permitAll() // 登录跳转 URL 无需认证/<code>
<code> .anyRequest() // 所有请求/<code>
<code> .authenticated() // 都需要认证/<code>
<code> .and().csrf().disable();/<code>
<code> }/<code>
<code> /<code>
<code>//加密模式/<code>
<code> @Bean/<code>
<code> public PasswordEncoder passwordEncoder() {/<code>
<code> return new BCryptPasswordEncoder();/<code>
<code> }/<code>
<code> /<code>
<code>}/<code>
基本的搭建流程就这些,下一篇介绍验证码,记住我,短信验证码的实现;
如果此处看着不方便,请移步http://xs-shuai.com/?p=73
閱讀更多 編程的boy 的文章