03.01 spring Security 快速搭建

sprring Security和shiro都是当前最流行的两个认真框架,一直都没有去学习,这段时间疫情的影响,一直在家办公,晚上的时候找时间学习了一下,spring Security,而且shiro的学习也是比较模糊,都没完整的了解过整个流程,接下来的一段时间先进行一下了解,出一系列的笔记.跟多配置参考:https://github.com/wuyouzhuguli/SpringAll ,github上发现的项目,初学者十分的实用


配置流程

  1. 引入pom依赖
  2. 创建user实体
  3. 配置userdetailservice,重写loaduserByUsername方法,用于数据库的查询用户的对象,获取权限等
  4. 配置登录成功和失败的handler
  5. 配置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


分享到:


相關文章: