Spring项目建立过程

1,导入依赖

导入Spring依赖

  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
   </dependency>

2,实现部分


2.1 自动给我们请求返回一个登录页面,(基于过滤器实现的)

直接写一个的登录的流程

dao-xml文件-service-controller

 完成以上操作后访问:http://localhost:8080/hello 结果打开的是一个登录页面,其实这时候我们的请求已经被保护起来了,要想访问,需要先登录


2.2: 认证

从数据库获取用户信息,器替换默认的账号

1,继承 WebSecurityConfigurerAdapter 重写 configure(AuthenticationManagerBuilder auth),然后自定义一个service 类,必须继承一个类 UserDetailsService 达到自定义一用户名和密码功能

     

 

2,重写 configure(HttpSecurity http) 方法,达到自定义登录页面功能

第一种:不是前后端分离的项目:需要指定登录页面地址,和配置表单action 地址。

 

第二种:是前后端分离的项目,就不许指定登录页面地址,和配置表单action 地址。

(注意:一定是post请求),从前端进入

 


2.3:授权


1,通过 调用该 http.authorizeRequests() 就可以达到访问控制了

 

.anyRequest().authenticated(); 所有的请求都拦截

 

2,通过antMatchers() 给url 配置访问权限

权限控制方法主要是4个:

* hasRole() 
* hasAnyRole()
* hasAuthority()
* hasAnyAuthority()  

3,通过注解式配置权限访问控制

3.1:添加 @EnableGlobalMethodSecurity 注解(注意三套注解方式,默认都是关闭状态,使用哪一类就打开)

 

例如使用 securedEnabled 配置注解方式 @EnableGlobalMethodSecurity(securedEnabled = true)

 

3.2: 以后开发主要用的注解方式 @PreAuthorize()

3.3:在service中同时给认证授权的赋予权限或者角色

上面的是调用的账号和密码

下面括号中的是赋予角色或者权限 ,在controller中也如上图对应一样才能实现功能或者页面访问,否则就无权限访问


2.4:配置一些处理器


都是用于前后端分离的项目

1:配置登录成功方发处理器 ,实现 AuthenticationSuccessHandler 接口

package cn.woniu.handler;

import cn.woniu.util.JWTUtil;
import cn.woniu.util.ResponseResult;
import com.alibaba.fastjson.JSON;

import org.apache.catalina.filters.ExpiresFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import sun.text.normalizer.ICUBinary;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 前后端分离的项目情况下,登录成功后,返回的不再是一个页面地址,,还是一个json
 * 处理用户登录成功后返回数据:比如用户等信息
 */
@Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler {



    @Autowired
    private RedisTemplate<String, String> redisTemplate;


    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
                                        HttpServletResponse response,
                                        Authentication authentication)
            throws IOException, ServletException {

        /**
         * 获取登录成功的用户信息
         */
        User user = (User) authentication.getPrincipal();
        try {
            redisTemplate.opsForValue().set("jwt:"+user.getUsername(),
                    JWTUtil.createJWT(user.getUsername()));
        } catch (Exception e) {
            e.printStackTrace();
        }

        //设置字符串
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter writer = response.getWriter();
        String json = JSON.toJSONString(ResponseResult.SECCUSS);
        writer.print(json);
        writer.flush();
        writer.close();
    }
}

2:配置登录失败方法处理器:实现 AuthenticationFailureHandler 接口

package cn.woniu.handler;

import cn.woniu.util.ResponseResult;
import com.alibaba.fastjson.JSON;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 登录失败后进入,返回给前端提示信息
 */
public class LoginFildHandler implements AuthenticationFailureHandler {
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        //设置字符串
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter writer = response.getWriter();
        String json = JSON.toJSONString(ResponseResult.FAIL);
        writer.print(json);
        writer.flush();
        writer.close();
    }
}

3:配置用户未登录直接访问我们系统资源,实现 AuthenticationEntryPoint 接口

package cn.woniu.handler;

import cn.woniu.util.ResponseResult;
import com.alibaba.fastjson.JSON;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 前后端分离项目情况下,用户未登录直接访问系统资源会被拦截
 */
public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint {


    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
//设置字符串
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter writer = response.getWriter();
        String json = JSON.toJSONString(ResponseResult.NOLOGIN);
        writer.print(json);
        writer.flush();
        writer.close();
    }
}

4:配置用户没有该资源访问权限情况下,实现 AccessDeniedHandler 接口

package cn.woniu.handler;

import cn.woniu.util.ResponseResult;
import com.alibaba.fastjson.JSON;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 虽然你知道用户名和密码
 * 但是,拦截你没有权限访问该资源操作
 *
 */
public class MyAccessDeniedHandler  implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        //设置字符串
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter writer = response.getWriter();
        String json = JSON.toJSONString(ResponseResult.NOAUTH);
        writer.print(json);
        writer.flush();
        writer.close();
    }
}

5:用户退出系统,实现LogoutSuccessHandler 接口

package cn.woniu.handler;

import cn.woniu.util.ResponseResult;
import com.alibaba.fastjson.JSON;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;


public class MyLogoutSuccessHandler implements LogoutSuccessHandler{

    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        //设置字符串
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter writer = response.getWriter();
        String json = JSON.toJSONString(ResponseResult.LOGOUT);
        writer.print(json);
        writer.flush();
        writer.close();
    }
}

JWT


导入依赖

<dependency>
    <groupId>com.nimbusds</groupId>
    <artifactId>nimbus-jose-jwt</artifactId>
    <version>9.11.1</version>
</dependency>

JWT 就是一个经过加密得到一个字符串,有三个部分组成,分别是:头部(放一些关于jwt本身相关的信息),载荷:(放用户登录成功后的信息,主要:不要放敏感信息),签名:(有头部加上载荷,经过密钥加密得到的一个字符串)

3.1,代码得到JWT


头部代码

 JWSHeader jwsHeader =new JWSHeader.
                Builder(JWSAlgorithm.HS256).
                type(JOSEObjectType.JWT).build();

载荷代码  

 //创建载荷
        Map map = new HashMap<>();
        map.put("username",username);
        Payload payload = new Payload(map);

签名代码

 JWSSigner jwsSigner = new MACSigner(KEY);
 JWSObject jwsObject = new JWSObject(jwsHeader,payload);
 jwsObject.sign(jwsSigner);

解密前后传过来的jwt

 JWSObject parse = JWSObject.parse(jwt);
 JWSVerifier jwsVerifier = new MACVerifier(KEY);
 return  parse.verify(jwsVerifier);

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值