springboot + springSecurity + jwt 实现用户访问认证和授权

本文讲述的是springboot集成springSecurity和JWT的实现。

前后端分离目前已成为互联网项目开发的业界标准,其核心思想就是前端(APP、小程序、H5页面等)通过调用后端的API接口,提交及返回JSON数据进行交互。
在前后端分离项目中,首先要解决的就是登录及授权的问题。传统的session认证限制了应用的扩展能力,无状态的JWT认证方法应运而生,该认证机制特别适用于分布式站点的单点登录(SSO)场景。

  

一,导入SpringSecurity与JWT的相关依赖

 

       <!--Security框架-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        
        <!-- jwt -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>0.10.6</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <version>0.10.6</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <version>0.10.6</version>
        </dependency>

  

二,定义SpringSecurity需要的基础处理类

  application-dev.properties 加入jwt配置信息  

##jwt
# 令牌key
jwt.header = Authorization
# 令牌前缀
jwt.token-start-with = Bearer
# 使用Base64对该令牌进行编码
jwt.base64-secret = U2FsdGVkX1/3Ox76xzrqllLe1lIgoHycDTgwVYrFQTPhG9V1lQPnLerFS/tmN1PzrQmx5243Nu9/iJf88neqOA==
# 令牌过期时间 此处单位/毫秒
jwt.token-validity-in-seconds = 14400000

  创建一个jwt的配置类,并注入Spring,便于程序中调用

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * @ProjectName: git-dev
 * @Package: com.lq.pys.base.config
 * @ClassName: JwtSecurityProperties
 * @Author: xxx
 * @Description: JWT配置类
 * @Date: 2021/2/18 10:55 上午
 */
@Data
@Configuration
@ConfigurationProperties(prefix = "jwt")
public class JwtSecurityProperties {

    /** Request Headers : Authorization */
    private String header;

    /** 令牌前缀,最后留个空格 Bearer */
    private String tokenStartWith;

    /** Base64对该令牌进行编码 */
    private String base64Secret;

    /** 令牌过期时间 此处单位/毫秒 */
    private Long tokenValidityInSeconds;

    /**返回令牌前缀 */
    public String getTokenStartWith() {
        return tokenStartWith + " ";
    }

}

  定义无权限访问类

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lq.pys.base.core.BDic;
import com.lq.pys.base.core.BaseOut;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;

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

/**
 * @ProjectName: git-dev
 * @Package: com.lq.pys.base.common
 * @ClassName: JwtAccessDeniedHandler
 * @Author: xxx
 * @Description: jwt无权限访问类
 * @Date: 2021/2/18 11:28 上午
 */
@Component
public class JwtAccessDeniedHandler implements AccessDeniedHandler {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        // 这个是自定义的返回对象,看各自需求
        BaseOut baseOut = new BaseOut();
        baseOut.setCode(BDic.FAIL);
        baseOut.setMessage("无权限查看此页面,请联系管理员!");
        baseOut.setTimestamp(Long.valueOf(System.currentTimeMillis()).toString());
        response.setContentType("application/json");
        response.setStatus(HttpServletResponse.SC_OK);
        try {
            ObjectMapper mapper = new ObjectMapper();
            mapper.writeValue(response.getOutputStream(), baseOut);
        } catch (Exception e) {
            throw new ServletException();
        }
    }
}    

 

  定义认证失败处理类

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lq.pys.base.core.BDic;
import com.lq.pys.base.core.BaseOut;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

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

/**
 * @ProjectName: git-dev
 * @Package: com.lq.pys.base.common
 * @ClassName: JwtAuthenticationEntryPoint
 * @Author: xxx
 * @Description: JWT认证失败处理类
 * @Date: 2021/2/18 11:31 上午
 */
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest request,
                         HttpServletResponse response,
                         AuthenticationException authException) throws IOException, ServletException {
        BaseOut baseOut = new BaseOut();
        baseOut.setCode(BDic.FAIL);
        baseOut.setMessage("无权限查看此页面,请联系管理员");
        baseOut.setTimestamp(Long.valueOf(System.currentTimeMillis()).toString());
        response.setContentType("application/json");
        response.setStatus(HttpServletResponse.SC_OK);
        try {
            ObjectMapper mapper = new ObjectMapper();
            mapper.writeValue(response.getOutputStream(), baseOut);
        } catch (Exception e) {
            throw new ServletException();
        }
    }
}

 

三,构建JWT token工具类

  工具类实现创建token与校验token功能

import com.lq.pys.base.config.JwtSecurityProperties;
import com.lq.pys.base.core.UserInfo;
import io.jsonwebtoken.*;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;

import java.security.Key;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ProjectName: git-dev
 * @Package: com.lq.pys.util
 * @ClassName: JwtTokenUtils
 * @Author: xxx
 * @Description: JWT
 * @Date: 2021/2/18 11:01 上午
 */
@Slf4j
@Component
public class JwtTokenUtils implements InitializingBean {

    private final JwtSecurityProperties jwtSecurityProperties;
    private static final String AUTHORITIES_KEY = "auth";
    private Key key;

    public JwtTokenUtils(JwtSecurityProperties jwtSecurityProperties) {
        this.jwtSecurityProperties = jwtSecurityProperties;
    }

    @Override
    public void afterPropertiesSet() {

        byte[] keyBytes = Decoders.BASE64.decode(jwtSecurityProperties.getBase64Secret());
        this.key = Keys.hmacShaKeyFor(keyBytes);
    }


    public String createToken (Map<String, Object> claims) {
        return Jwts.builder()
                .claim(AUTHORITIES_KEY, claims)
                .setId(UUID.randomUUID().toString())
                .setIssuedAt(new Date())
                .setExpiration(new Date((new Date()).getTime() + jwtSecurityProperties.getTokenValidityInSeconds()))
                .compressWith(CompressionCodecs.DEFLATE)
                .signWith(key, SignatureAlgorithm.HS512)
                .compact();
    }

    public Date getExpirationDateFromToken(String token) {
        Date expiration;
        try {
            final Claims claims = getClaimsFromToken(token);
            expiration = claims.getExpiration();
        } catch (Exception e) {
            expiration = null;
        }
        return expiration;
    }

    public Authentication getAuthentication(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(key)
                .parseClaimsJws(token)
                .getBody();

        Collection<? extends GrantedAuthority> authorities =
                Arrays.stream(claims.get(AUTHORITIES_KEY).toString().split(","))
                        .map(SimpleGrantedAuthority::new)
                        .collect(Collectors.toList());

        HashMap map =(HashMap) claims.get("auth");

        UserInfo principal = new UserInfo(map);

        return new UsernamePasswordAuthenticationToken(principal, token, authorities);
    }

    public boolean validateToken(String authToken) {
        try {
            Jwts.parser().setSigningKey(key).parseClaimsJws(authToken);
            return true;
        } catch (io.jsonwebtoken.security.SecurityException | MalformedJwtException e) {
            log.error("token失效",e);
        } catch (ExpiredJwtException e) {
            log.error("token过期",e);
        } catch (UnsupportedJwtException e) {
            log.error("无效的token",e);
        } catch (IllegalArgumentException e) {
            log.error("处理token异常.",e);
        }
        return false;
    }

    private Claims getClaimsFromToken(String token) {
        Claims claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey(key)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            claims = null;
        }
        return claims;
    }
}

 

四,实现token验证的过滤器

  该类继承OncePerRequestFilter,它能够确保在一次请求中只通过一次filter。该类使用JwtTokenUtils工具类进行token校验。

import com.lq.pys.base.common.SpringContextHolder;
import com.lq.pys.base.config.JwtSecurityProperties;
import com.lq.pys.util.JwtTokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

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

/**
 * @ProjectName: git-dev
 * @Package: com.lq.pys.base.filter
 * @ClassName: JwtAuthenticationTokenFilter
 * @Author: xxx
 * @Description: JWT过滤器
 * @Date: 2021/2/18 11:07 上午
 */
@Component
@Slf4j
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private JwtTokenUtils jwtTokenUtils;

    public JwtAuthenticationTokenFilter(JwtTokenUtils jwtTokenUtils) {
        this.jwtTokenUtils = jwtTokenUtils;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        JwtSecurityProperties jwtSecurityProperties = SpringContextHolder.getBean(JwtSecurityProperties.class);
        String requestRri = httpServletRequest.getRequestURI();
        //获取request token
        String token = null;
        String bearerToken = httpServletRequest.getHeader(jwtSecurityProperties.getHeader());
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(jwtSecurityProperties.getTokenStartWith())) {
            token = bearerToken.substring(jwtSecurityProperties.getTokenStartWith().length());
        }

        if (StringUtils.hasText(token) && jwtTokenUtils.validateToken(token)) {
            Authentication authentication = jwtTokenUtils.getAuthentication(token);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            log.debug("set Authentication to security context for '{}', uri: {}", authentication.getName(), requestRri);
        } else {
            log.debug("no valid JWT token found, uri: {}", requestRri);
        }
        filterChain.doFilter(httpServletRequest, httpServletResponse);

    }
}

  根据SpringBoot官方让重复执行的filter实现一次执行过程的解决方案,参见官网地址:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-disable-registration-of-a-servlet-or-filter
需在SpringBoot启动类中,加入以下代码:  

 /**
     * @Description:
     * @param filter:
     * @return: org.springframework.boot.web.servlet.FilterRegistrationBean
     * @author: xxx
     * @date: 2021/2/18 11:14 上午
     */
    @Bean
    public FilterRegistrationBean registration(JwtAuthenticationTokenFilter filter) {
        FilterRegistrationBean registration = new FilterRegistrationBean<>(filter);
        registration.setEnabled(false);
        return registration;
    }

 

五,SpringSecurity的关键配置

  SpringBoot推荐使用配置类来代替xml配置,该类中涉及了以上几个bean来供security使用

  • JwtAccessDeniedHandler :无权限访问
  • jwtAuthenticationEntryPoint :认证失败处理
  • jwtAuthenticationTokenFilter :token验证的过滤器
import com.lq.pys.base.exception.JwtAccessDeniedHandler;
import com.lq.pys.base.exception.JwtAuthenticationEntryPoint;
import com.lq.pys.base.filter.JwtAuthenticationTokenFilter;
import com.lq.pys.util.JwtTokenUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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.config.http.SessionCreationPolicy;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * @ProjectName: git-dev
 * @Package: com.lq.pys.base.config
 * @ClassName: WebSecurityConfig
 * @Author: xxx
 * @Description: SpringSecurity关键配置
 * @Date: 2021/2/18 11:20 上午
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private final JwtAccessDeniedHandler jwtAccessDeniedHandler;
    private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
    private final JwtTokenUtils jwtTokenUtils;

    public WebSecurityConfig(JwtAccessDeniedHandler jwtAccessDeniedHandler, JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint, JwtTokenUtils jwtTokenUtils) {
        this.jwtAccessDeniedHandler = jwtAccessDeniedHandler;
        this.jwtAuthenticationEntryPoint = jwtAuthenticationEntryPoint;
        this.jwtTokenUtils = jwtTokenUtils;
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                // 禁用 CSRF
                .csrf().disable()
                // 授权异常
                .exceptionHandling()
                .authenticationEntryPoint(jwtAuthenticationEntryPoint)
                .accessDeniedHandler(jwtAccessDeniedHandler)
                // 不创建会话
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                // 放行swagger
                .antMatchers("/swagger-ui.html").permitAll()
                .antMatchers("/swagger-resources/**").permitAll()
                .antMatchers("/webjars/**").permitAll()
                .antMatchers("/*/api-docs").permitAll()
                // 跨域请求会先进行一次options请求 必须放行的OPTIONS请求
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                //允许匿名及登录用户访问
                .antMatchers("/api/auth/**", "/error/**").permitAll()

                // 不需要token的访问
                .antMatchers("/admin/**").permitAll()
                .antMatchers("/login/**").permitAll()
                .antMatchers("/sms/**").permitAll()
                .antMatchers("/membersTypeInfo/**").permitAll()
                .antMatchers("/membersClassInfo/**").permitAll()
                .antMatchers("/membersRightsInfo/**").permitAll()
                .antMatchers("/oss/**").permitAll()
                .antMatchers("/storeUser/**").permitAll()
                .antMatchers("/imgConfigure/**").permitAll()
                .antMatchers("/userMembersInfo/**").permitAll()

//                .antMatchers("/sms/**").permitAll()

                // 所有请求都需要认证
                .anyRequest().authenticated();

        // 禁用缓存
        httpSecurity.headers().cacheControl();

        // 添加JWT filter
        httpSecurity.apply(new TokenConfigurer(jwtTokenUtils));

    }

    public class TokenConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {

        private final JwtTokenUtils jwtTokenUtils;

        public TokenConfigurer(JwtTokenUtils jwtTokenUtils){

            this.jwtTokenUtils = jwtTokenUtils;
        }

        @Override
        public void configure(HttpSecurity http) {
            JwtAuthenticationTokenFilter customFilter = new JwtAuthenticationTokenFilter(jwtTokenUtils);
            http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class);
        }
    }
}

 

六,编写Controller/Service进行测试

  登录后可以使用 LoginUserUtilV3.getLoginUser().getUserOperationId(); 获取用户信息

/**
 * @ProjectName: git-dev
 * @Package: com.lq.pys.system.controller
 * @ClassName: AdminLoginController
 * @Author: xxx
 * @Description: 后台登录 控制器
 * @Date: 2021/2/8 1:23 下午
 */
@RestController
@RequestMapping("/admin/login/")
public class AdminLoginController extends ZyBaseController {

    @Autowired
    private LoginService loginService;

    /**
     * @param in:
     * @Description: Admin 密码登录
     * @return: com.lq.pys.base.core.BaseOut
     * @author: xxx
     * @date: 2021/2/8 10:18 上午
     */
    @PostMapping("password")
    public BaseOut password(@RequestBody @Validated(value = {PasswordLogin.class}) LoginIn in) {
        in.setLoginType(LoginDic.LOGIN_TYPE.PASSWORD);
        LoginAdminUserOut loginAdminUserOut = loginService.adminLogin(in);
        return setSuccessBaseOut(loginAdminUserOut);
    }
}
/**
 * @ProjectName: git-dev
 * @Package: com.lq.pys.system.service
 * @ClassName: LoginService
 * @Author: xxx
 * @Description: 登录业务处理
 * @Date: 2021/2/8 9:33 上午
 */
@Slf4j
@Service
public class LoginService {

    @Autowired
    protected SysUserService sysUserService;
    @Autowired
    protected CaptchaService captchaService;
    @Autowired
    private JwtTokenUtils jwtTokenUtils;


    /**
     * @Description: Admin 用户登录
     * @param in:
     * @return: com.lq.pys.system.login.out.LoginAdminUserOut
     * @author: xxx
     * @date: 2021/2/8 10:44 上午
     */
    public LoginAdminUserOut adminLogin(LoginIn in) {

        /** 校验用户名/密码/图片验证码 */
        SysUser sysUser = sysUserService.getUserByAccount(in.getAccount());
        Optional.ofNullable(sysUser).orElseThrow(()->new BusinessException("用户不存在,不允许登录"));
        Optional.ofNullable(sysUser.getPassword()).filter(s->sysUser.getPassword().equals(SecurityUtil.pwdEncrypt(in.getPassword()))).orElseThrow(()->new BusinessException("登录密码错误,请重新输入"));
//        captchaService.check(in.getImageCodekey(),in.getImageCode());

        LoginAdminUserOut loginAdminUserOut = new LoginAdminUserOut();
        /** 设置用户信息 */
        AdminUserOut adminUserOut = new AdminUserOut();
        BeanUtils.copyProperties(sysUser,adminUserOut);
        loginAdminUserOut.setUserInfo(adminUserOut);
        /** 设置用户权限 */

        /** 设置token */
        String token = jwtTokenUtils.createToken(convertToMap(adminUserOut));
        loginAdminUserOut.setToken(token);

        return loginAdminUserOut;
    }
}

  使用IDEA Rest Client测试如下:

 

 

  无token和token失效返回的错误信息:

 

 

 

 

  使用到的用户对象的类:

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.lq.pys.system.dto.sys.ZySysRole;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

@Data
public class LoginUserV3 implements UserDetails {

    /**
     * 业务ID
     */
    private String userOperationId;

    /**
     * 登录帐户
     */
    private String account;

    /**
     * 手机号
     */
    private String phone;

    /**
     * 密码
     */
    private String password;

    /**
     * 邀请码
     */
    private String invitation;

    /**
     * 创建时间
     */
    private Date createTime;

    /**
     * 是否是章鱼管理员
     */
    private Boolean isZyAdmin = false;

    /**
     * 登陆UUID
     */
    private String loginUUID;

    private Set<ZySysRole> sysRoles;

    private Set<String> permissions;

    @JsonIgnore
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        Collection<GrantedAuthority> collection = new HashSet<>();
        if (!CollectionUtils.isEmpty(sysRoles)) {
            sysRoles.parallelStream().forEach(role -> {
                if (role.getRole_name().startsWith("ROLE_")) {
                    collection.add(new SimpleGrantedAuthority(role.getRole_name()));
                } else {
                    collection.add(new SimpleGrantedAuthority("ROLE_" + role.getRole_name()));
                }
            });
        }

        if (!CollectionUtils.isEmpty(permissions)) {
            for (String per : permissions){
                collection.add(new SimpleGrantedAuthority(per));
            }
        }

        return collection;
    }

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

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

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

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

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

  全局获取用户对象的工具类

import com.alibaba.fastjson.JSONObject;
import com.lq.pys.base.core.UserInfo;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

public class LoginUserUtilV3 {

    /**
     * @Description: 获取登录信息
     * @param :
     * @return: com.lq.pys.system.login.LoginUserV3
     * @author: xxx
     * @date: 2021/2/21 19:04 上午
     */
    public static LoginUserV3 getLoginUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication instanceof UsernamePasswordAuthenticationToken) {
            UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) authentication;
            Object str = authenticationToken.getPrincipal();
            UserInfo userInfo = (UserInfo) str;
            LoginUserV3 loginUserV3 = JSONObject.parseObject(JSONObject.toJSONString(userInfo), LoginUserV3.class);
            return loginUserV3;
        }
        return null;
    }
}

  用户实体类:

/**
 * @ProjectName: git-dev
 * @Package: com.lq.pys.util
 * @ClassName: UserInfo
 * @Author: xxx
 * @Description: 用户信息类
 * @Date: 2021/2/18 11:01 上午
 */
@Data
public class UserInfo implements Serializable{

    private static final long serialVersionUID = 4768132985889604776L;

    /** 用户ID */
    private Long id;
    /** 用户业务id */
    private String userOperationId;
    /**  用户账号 */
    private String account;
    /**  用户密码 */
    private String password;

    public UserInfo(HashMap map){
        this.userOperationId =  map.get("operationId").toString();
        this.account =  map.get("account").toString();
        this.password = map.get("password").toString();
    }

}

 

解决跨域问题:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/**
 * @ProjectName: git-dev
 * @Package: com.lq.pys.base.config
 * @ClassName: CorsConfig
 * @Author: xxx
 * @Description: 解决跨域问题
 * @Date: 2021/2/18 1:39 下午
 */
@Configuration
public class CorsConfig {

    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();

        /**
         * 你需要跨域的地址  注意这里的 127.0.0.1 != localhost
         * 表示只允许http://localhost:8080地址的访问(重点哦!!!!)
         * corsConfiguration.addAllowedOrigin("http://localhost:8080");
         */
        //允许所有域名进行跨域调用
        corsConfiguration.addAllowedOrigin("*");
        //放行全部原始头信息
        corsConfiguration.addAllowedHeader("*");
        //允许所有请求方法跨域调用
        corsConfiguration.addAllowedMethod("*");
        //允许跨越发送cookie
        corsConfiguration.setAllowCredentials(true);

        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        //配置 可以访问的地址
        source.registerCorsConfiguration("/**", buildConfig()); // 4
        return new CorsFilter(source);
    }

 

麻麻思day.

 

 

 

  

posted @ 2021-03-04 15:48  姜饼攻城狮  阅读(1048)  评论(0编辑  收藏  举报