Spring Security安全框架

安全管理:

认证:确认用户是否登录,对登录进行管控

授权:确定用户的权限,对用户权限进行管理

步骤:

1.添加依赖

启动项目,自定义进行安全管理(默认的安全管理模式)

2.自定义安全管理配置

创建配置类:webSecurityConfigureAdapter(去继承它)

重写这两个方法:

config(AuthenticationManagerBuilder auth):设置认证方式

config(HttpSecuritr http):设置访问控制

还有给这个类加上这个注解

@EnableWebSecurity:开启MVC Security安全支持

JDBC认证:

创建表格:

用户表: 

            username:值唯一

            布尔类型的字段:用户是否有效

            密码:必须进行加密操作

权限表:

           数据要求:

                  ROLE_名字

用户权限关联关系表:

进行jdbc认证sql:

(1)查询username、password、validate(用户是否有效)

(2)查询username、authority(权限)

创建工具类(config层)

SecurityConfig类
package com.lxyk.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.security.servlet.WebSecurityEnablerConfiguration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.IOException;
import java.util.Collection;

/**
 * 登录判断
 */
@EnableWebSecurity    //开启MVC Security安全支持
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    DataSource dataSource;
    @Value("${COOKIE.VALIDITY}")
    private Integer validate;

    //设置访问控制
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //1.自定义用户访问控制
        http.authorizeRequests()
            .antMatchers("/", "/articleDetial/**", "/page/**", "/login")
            .permitAll()
            .antMatchers("/article_img/**", "/assets/**", "/back/**", "/user/**")
            .permitAll()
            .antMatchers("/admin/**")
            .hasRole("admin")
            .anyRequest()
            .authenticated(); //hasRole:管理进入后台,第一个antMatchers代表前端放行,后面的代表要权限管理
        //2.登录控制
        http.formLogin()
            .loginPage("/login")               //登录页面的跳转路径(如果要跳转到自己的登录页面,就向后台发送这个请求)
            .usernameParameter("username")
            .passwordParameter("password")
            //判断成功或失败
            .successHandler(new AuthenticationSuccessHandler() {
                @Override
                public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                    //1.获取到拦截页面
                    HttpSessionRequestCache requestCache = new HttpSessionRequestCache();          //Http 会话请求缓存
                    //2.跳转到当时访问过来的页面(如:在付款的时候选择登录)
                    String url = httpServletRequest.getParameter("url");
                    SavedRequest request = requestCache.getRequest(httpServletRequest, httpServletResponse);
                    //在从request中获取到页面的拦截地址
                    //判断
                    if (request != null) {
                        //跳转到拦截地址页面
                        httpServletResponse.sendRedirect(request.getRedirectUrl());             //重定向到 从请求域中获取到的获取重定向网址
                    } else if (url != null & url != "") {
                        //跳转到原始访问页面(如:在付款的时候选择登录)
                        httpServletResponse.sendRedirect(url);
                    } else {
                        //提转到主页
                        //既然要跳转到主页,那么:如果是管理员admin--》后台首页 /admin
                        //如果不是管理员 --》前台首页                      /
                        //怎么获取权限?
                        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();       //获取到权限
                        //当前用户可能有多个权限,所以是Collection
                        boolean isAdmin = authorities.contains(new SimpleGrantedAuthority("ROLE_admin"));//判断它里面有没有
                        if (isAdmin) {
                            //如果是管理员admin--》后台首页 /admin
                            httpServletResponse.sendRedirect("/admin");
                        } else {
                            //如果不是管理员 --》前台首页
                            httpServletResponse.sendRedirect("/");
                        }
                    }

                }
            })
            //失败
            .failureHandler(new AuthenticationFailureHandler() {
                @Override
                public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
                    //回到登录页面,重新登录
                    //获取原始访问路径
                    String url = httpServletRequest.getParameter("url");
                    httpServletResponse.sendRedirect("/login?error&url=" + url);         //这里有个小细节error前端页面login中有如果登录错误会有提示信息,带着这个就会显示提示
                }
            });

        //3.退出控制
        http.logout()
            .logoutUrl("/logout")      //退出
            .logoutSuccessUrl("/");    //退出后回到首页
        //4 是否要开启记住我工能,设置cookie有效时间
        http.rememberMe().alwaysRemember(true).tokenValiditySeconds(validate);    //记住密码
    }

    //设置认证方式
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //JDBC方式认证
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        //JDBC身份认证SQL
        //查询用户
        String useSQL = "select username,password,valid from t_user where username=?";
        //查询权限
        String authoritySQL = "select a.username,b.authority " +
                "from t_user a,t_authority b,t_user_authority c " +
                "where a.id=c.user_id and b.id=c.authority_id and username=?";
        auth.jdbcAuthentication()
            .passwordEncoder(encoder)
            .dataSource(dataSource)
            .usersByUsernameQuery(useSQL)
            .authoritiesByUsernameQuery(authoritySQL);
    }
}

控制层添加方法

    /**
     * 登录跳转请求:跳转到登录页面
     * @param request 请求域 获取原始访问路径和获取要额外去保存的路径
     * @param map 把路径保存进去
     * @return 把这个路径返回到登录页面当中
     */
    @RequestMapping("/login")
    public String longin(HttpServletRequest request, Map map) {
        //保存原始访问路径 作用:往SecurityConfig工具类里送,保证它的功能
        String referer = request.getHeader("Referer");     //获取原始访问路径,还需要去判断,不能直接用。因为如果登陆失败了存的就是失败的路径
        String url = request.getParameter("url");          //获取原始访问路径(额外要去保存的)
        System.out.println("referer=" + referer);
        System.out.println("url=" + url);
        //1.先判断保存的url
        if (url != null && url != "") {
            //使用url作为原始访问路径
            map.put("url",url);
        }else if (referer!=null&&referer.contains("login")){
            //2.如果头信息中有login字段(是从登录---》登录)
            map.put("url","");
        }else {
            //3.头信息作为原始访问路径
            map.put("url",referer);
        }
        //跳转到登录页面
        return "comm/login";
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值