spring boot + spring security + ajax 实现登录退出session管理

登录验证–> 权限管理–>session 设置

Maven导入jar包

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.66</version>
        </dependency>

数据库设计

   --用户表
       CREATE TABLE L_USER (
			ID NUMBER NULL ,
			USERNAME VARCHAR2(30 BYTE) NULL ,
			PASSWORD VARCHAR2(255 BYTE) NULL ,
			ENABLED NUMBER NULL ,
			LOCKED NUMBER NULL 
		)
		-- 权限表
		CREATE TABLE L_ROLE (
			ID NUMBER NULL ,
			NAME VARCHAR2(50 BYTE) NULL ,
			NAMEZH VARCHAR2(50 BYTE) NULL 
		)
		-- 用户权限关联表
		CREATE TABLE L_USER_ROLE (
			ID NUMBER NULL ,
			USERID NUMBER NULL ,
			ROLEID NUMBER NULL 
		)

创建实体类

@ApiModel(value = "用户实体类", description = "用户信息描述类")
public class User implements UserDetails {
    @ApiModelProperty(value = "用户名id")
    private Integer id ;
    @ApiModelProperty(value = "用户名")
    private String username ;
    @ApiModelProperty(value = "密码")
    private String password ;
    @ApiModelProperty(value = "是否可用")
    private Boolean enabled ;
    @ApiModelProperty(value = "是否锁定")
    private Boolean locked ;
    @ApiModelProperty(value = "角色")
    private List<Role> roles ;
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
       List<SimpleGrantedAuthority> authorities =  new ArrayList<>();
       for(Role role : roles){
            authorities.add(new SimpleGrantedAuthority(role.getName()));
       }
        return authorities;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return !locked;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return enabled;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }
  // 这个一定要注释掉,会重复
   /* public Boolean getEnabled() {
        return enabled;
    }*/

    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }

    public Boolean getLocked() {
        return locked;
    }

    public void setLocked(Boolean locked) {
        this.locked = locked;
    }

    public List<Role> getRoles() {
        return roles;
    }

    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }

    public User() {
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", enabled=" + enabled +
                ", locked=" + locked +
                ", roles=" + roles +
                '}';
    }
}
public class Role {
    private Integer id ;
    private String name ;
    private String nameZH;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNameZH() {
        return nameZH;
    }

    public void setNameZH(String nameZH) {
        this.nameZH = nameZH;
    }

    @Override
    public String toString() {
        return "Role{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", nameZH='" + nameZH + '\'' +
                '}';
    }
}
public class Result {
    private Integer code ;
    private String message ;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

Mapper文件(部分代码省去,只有sql语句)

	<select id="loadUserByUsername"  resultType="com.springtest.model.User">
			SELECT *  FROM l_user where username = #{username}
		</select>
	<select id="getUserRolesByUid" resultType="com.springtest.model.Role">
			select a.*,b.NAME,b.NAMEZH
			from
			L_USER_ROLE a LEFT JOIN L_ROLE b
			on a.ROLEID = b.ID
			where a.USERID = #{id}
	</select>

UserService 准备

@Service
public class UserService implements UserDetailsService {
    @Autowired
    UserMapper userMapper;
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        User user = userMapper.loadUserByUsername(s);
        if(user == null){
            throw new UsernameNotFoundException("用户名不存在");
        }
        user.setRoles(userMapper.getUserRolesByUid(user.getId()));
        return user;
    }
}

登录,权限验证

@Configuration
//@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    UserService userService;
    @Autowired
    MyAuthenticationFailHandler authenticationFailHandler;
    @Autowired
    MyAuthenticationSuccessHandler authenticationSuccessHandler;
    @Autowired
    CustomAccessDeniedHandler deniedHandler;
    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/js/**","/login_page.html");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService);
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
               .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
                    @Override
                    public <O extends FilterSecurityInterceptor> O postProcess(O o) {
                        o.setSecurityMetadataSource(cfisms());
                        o.setAccessDecisionManager(cadm());
                        return o;
                    }
                })
               /*.antMatchers("/admin/**").hasRole("admin")
                .antMatchers("/db/**").hasRole("dba")*/
                .anyRequest()
                .authenticated()
                .and()
                .formLogin()
                .loginPage("/login_page.html")
                .loginProcessingUrl("/login")
                //.successForwardUrl("/index.html")
                .permitAll()
                .failureHandler(authenticationFailHandler)
                .successHandler(authenticationSuccessHandler)
                .and()
                .logout()
                .logoutUrl("/logout")
                .clearAuthentication(true)
                .invalidateHttpSession(true)
                .logoutSuccessHandler(new LogoutSuccessHandler() {
                    @Override
                    public void onLogoutSuccess(HttpServletRequest httpServletRequest,
                                                HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                        httpServletResponse.setStatus(HttpServletResponse.SC_OK);
                        httpServletResponse.setContentType("application/json; charset=utf-8");
                        PrintWriter writer = httpServletResponse.getWriter();
                        Result result = new Result();
                        result.setCode(1);
                        result.setMessage("退出成功");
                        writer.write(new ObjectMapper().writeValueAsString(result));
                        writer.flush();
                        writer.close();
                    }
                })
                .permitAll()
                .and()
                .csrf().disable()
                .exceptionHandling()
                .accessDeniedHandler(deniedHandler)
                .and()
                .sessionManagement() //session超时管理
                .invalidSessionUrl("/login_page.html"); //session超时跳向的url;
    }
    @Bean
    CustomFilterInvocationSecurityMetadataSource cfisms(){
        return new CustomFilterInvocationSecurityMetadataSource();
    }
    @Bean
    CustomAccessDecisionManager cadm(){
       return new CustomAccessDecisionManager();
    }
}
----------------------------------------------------------------
@Component
public class CustomFilterInvocationSecurityMetadataSource
        implements FilterInvocationSecurityMetadataSource {
    AntPathMatcher antPathMatcher = new AntPathMatcher();
    @Autowired
    MenuMapper menuMapper;
    @Override
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
        String requestUrl = ((FilterInvocation) o).getRequestUrl();
        List<Menu> menus = menuMapper.getAllMenus();
        for(Menu menu : menus){
          if(antPathMatcher.match(menu.getPattern(),requestUrl)){
              List<Role> roles = menu.getRoles();
              String[] roleArr = new String[roles.size()];
              for(int i=0 ;i < roleArr.length ; i++){
                  roleArr[i] = roles.get(i).getName();
              }
              return SecurityConfig.createList(roleArr);

          }
        }
        return SecurityConfig.createList("ROLE_LOGIN");
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return FilterInvocation.class.isAssignableFrom(aClass);
    }
}
----------------------------------------------------------------------------------
@Component
public class CustomAccessDecisionManager implements AccessDecisionManager {
    @Override
    public void decide(Authentication authentication, Object o, Collection<ConfigAttribute> collection) throws AccessDeniedException, InsufficientAuthenticationException {
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        for (ConfigAttribute configAttribute : collection){
            if("ROLE_LOGIN".equals(configAttribute.getAttribute())
                    && authentication instanceof UsernamePasswordAuthenticationToken){
                    return;
            }
            for (GrantedAuthority authority : authorities){
                if(configAttribute.getAttribute().equals(authority.getAuthority())){
                    return;
                }
            }
        }
        throw  new AccessDeniedException("权限不足");
    }

    @Override
    public boolean supports(ConfigAttribute configAttribute) {
        return true;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}
-------------------------------------------------------------------------------
@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
    private String errorPage;
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
        httpServletResponse.setStatus(HttpServletResponse.SC_OK);
        httpServletResponse.setContentType("application/json; charset=utf-8");
        PrintWriter writer = httpServletResponse.getWriter();
        Result result = new Result();
        result.setCode(0);
        result.setMessage("权限不足");
        //httpServletResponse.sendRedirect("/login_page.html");
        writer.write(new ObjectMapper().writeValueAsString(result));
        writer.flush();
        writer.close();

    }
}
-------------------------------------------------------------------------------------------
@Component
public class MyAuthenticationFailHandler implements AuthenticationFailureHandler {
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
                                        AuthenticationException e) throws IOException {

        response.setStatus(HttpServletResponse.SC_OK);
        response.setContentType("application/json; charset=utf-8");
        PrintWriter writer = response.getWriter();
        Result result = new Result();
        result.setCode(0);
        if(e instanceof BadCredentialsException || e instanceof UsernameNotFoundException){
            result.setMessage("账户名或者密码不正确");
        }else if(e instanceof LockedException){
            result.setMessage("账户被锁定,请联系管理员");
        }else if(e instanceof CredentialsExpiredException){
            result.setMessage("密码过期,请联系管理员");
        }else if(e instanceof AccountExpiredException){
            result.setMessage("账户过期,请联系管理员");
        }else if(e instanceof DisabledException){
            result.setMessage("账户被禁,请联系管理员");
        }else {
            result.setMessage("登陆失败");
        }

        writer.write(new ObjectMapper().writeValueAsString(result));
        writer.flush();
        writer.close();




    }
}
-------------------------------------------------------------------------------------
@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException {
        httpServletResponse.setStatus(HttpServletResponse.SC_OK);
        httpServletResponse.setContentType("application/json; charset=utf-8");
        PrintWriter writer = httpServletResponse.getWriter();
        Result result = new Result();
        result.setCode(1);
        result.setMessage("登录成功");
        writer.write(new ObjectMapper().writeValueAsString(result));
        writer.flush();
        writer.close();
        //httpServletResponse.sendRedirect("/index.html");
    }
}

配置session过期时间

server:
  servlet:
    session:
      timeout: 600 #秒

测试(ajax)

--------------------登录-------------------------
    $('#btn').click(function () {
       var username = $('#username').val();
       var password = $('#password').val();
       $.ajax({
           url: '/login',
           type: "post",
           dataType: 'json',
           data: {
               username:username,
               password:password
           },
           success: function (res) {
               console.log(res);
               if (res.code == '0'){
                   alert(res.message);
               }else{
                  // $(location).attr('href','/index.html');
                  location.href = "index.html";
               }
           },
           error: function (e) {
               console.log(e);
           }

       })
   })
   ---------------------------退出------------------------------
       $('#btn').click(function () {
       $.ajax({
           url: '/logout',
           type: "post",
           dataType: 'json',
           data: {
              id:1
           },
           success: function (res) {
               console.log(res);
               if (res.code == '0'){
                  // alert('权限不足');
               }else{
                   location.href = "login_page.html";
               }
           },
           error: function (e) {
               console.log(e);
           }

       })
   })
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值