贴工程目录,其中bll目录下是service+dao层,common是一些公用的模块及功能类,web是controller层

用到了druid及Redis,工具及配置类目录(本文不介绍如何配置druid及Redis,但是我会把源文件放上)

web文件目录结构

接下来,说下大体的学习研究思路,在这块我是分了三部分来做验证的,这三部分只有securityconfig配置类有所区别

  第一部分就是前后端不分离的security认证;

  第二部是前后端分离,使用security+JWT认证;

  第三部分是一个项目中既包含前段的web验证,也包含API的jwt认证;

一、第一部分的验证:

pom文件

 1        <!-- security -->
 2         <dependency>
 3             <groupId>org.springframework.boot</groupId>
 4             <artifactId>spring-boot-starter-security</artifactId>
 5         </dependency>
 6         <!-- jwt -->
 7         <dependency>
 8             <groupId>io.jsonwebtoken</groupId>
 9             <artifactId>jjwt</artifactId>
10             <version>0.9.0</version>
11         </dependency>    

配置类中会用到的常量参数

# JWT
jwt.secret=secret
## 过期时间 毫秒
jwt.expiration=7200000
## 请求头
jwt.token_header=Authorization
## token 前缀
jwt.token_prefix=Bearer 

spring security configuration配置类

package com.ek.security.config;

import com.ek.security.EkUserDetailsService;
import com.ek.security.handler.EkAuthenticationEntryPoint;
import com.ek.security.handler.EkAuthenticationFailureHandler;
import com.ek.security.handler.EkAuthenticationSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.util.matcher.RequestMatcher;

import javax.servlet.http.HttpServletRequest;
/**
 * @ClassName: EkWebSecurityConfig
 * @Description: 前后端不分离的security安全认证
 * @Author: edi_kai
 * @Version: V2.0
 **/
@Configuration
public class EkWebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private EkUserDetailsService userDetailsService;
    @Autowired
    private EkAuthenticationEntryPoint authenticationEntryPoint;
    @Autowired
    private EkAuthenticationFailureHandler authenticationFailureHandler;
    @Autowired
    private EkAuthenticationSuccessHandler authenticationSuccessHandler;
    @Autowired
    PasswordEncoder passwordEncoder;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 添加自定义认证
        auth
            .userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder)
        ;
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        http.authorizeRequests().antMatchers("/**").permitAll();
        http.csrf().disable() //此处必须设置csrf disable,原因还不知道,对CSRF不太了解,后续我会查一下资料,然后在补充说明
//            .and()
                .httpBasic().authenticationEntryPoint(authenticationEntryPoint) // 没有凭证的操作,该部分不需要,可以不添加
            .and()
                .authorizeRequests()
                .antMatchers("/", "/index", "/toLogin", "/fail", "/druid/**").permitAll()  //需要忽略的请求链接
                .anyRequest().authenticated()
    //            .access("@rbacauthorityservice.hasPermission(request,authentication)") // RBAC 动态 url 认证
            .and()
                .formLogin().loginPage("/index") //指定自己的登录页面
                .loginProcessingUrl("/toLogin") // 登录action
                .usernameParameter("logName")  // 登录用户名
                .passwordParameter("password")  //密码
                .defaultSuccessUrl("/success", false) //设置登陆成功后跳转的页面
                .failureHandler(authenticationFailureHandler) //登录失败拦截器,也可以配置到指定的失败页面,我没写
//                .successHandler(authenticationSuccessHandler)
            .and()
                .logout()
        ;
    }
}

接下来看下该配置类中用到的其他配置类

EkUserDetails用户认证实体类,自己添加get/set方法,基本的Java类,不需要添加任何注解

private String loginName;
private String password;
private String userName;
private String userId;
private Set<? extends GrantedAuthority> authorities; // 权限

EkUserDetailsService登录认证,我这边没有配置权限,只是为了验证spring-security

package com.ek.security;

import com.ek.bean.base.EkUser;
import com.ek.service.base.IEkUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

/**
 * @ClassName: EkUserDetailsService
 * @Description: TODO
 * @Author: edi_kai
 * @Date: 2019-08-06
 * @Version: V2.0
 **/

@Component
public class EkUserDetailsService implements UserDetailsService {
    private Logger log = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private IEkUserService userService;
    @Override
    public UserDetails loadUserByUsername(String loginName) throws UsernameNotFoundException {
        EkUserDetails userDetails = null;
        EkUser dbUser = userService.selectByLogName(loginName);
        if (null != dbUser){
            userDetails = new EkUserDetails();
            userDetails.setLoginName(dbUser.getLogName());
            userDetails.setPassword(dbUser.getPassWord());
            userDetails.setUserName(dbUser.getUserName());
        }else {
            log.error("{} is not exist.", loginName);
            throw new UsernameNotFoundException(String.format("%s is not exist.", loginName));
        }
        return userDetails;
    }
}

EkAuthenticationEntryPoint 未登录的配置类

package com.ek.security.handler;
import com.alibaba.fastjson.JSON;
import com.ek.msg.JsonMsg;
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;
/**
 * @ClassName: EkAuthenticationEntryPoint
 * @Description: TODO
 * @Author: edi_kai
 * @Date: 2019-08-06
 * @Version: V2.0
 **/
@Component
public class EkAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
        httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        httpServletResponse.setHeader("Access-Control-Allow-Credentials","true");
        // 设定类容为json的格式
        httpServletResponse.setContentType("application/json;charset=UTF-8");
        JsonMsg jsonMsg = new JsonMsg();
        jsonMsg.setCode(402);
        jsonMsg.setMsg("未登录");
        httpServletResponse.getWriter().write(JSON.toJSONString(jsonMsg));
        httpServletResponse.sendError(402,"未登录");
    }
}

 EkAuthenticationFailureHandler 认证失败配置类

@Component
public class EkAuthenticationFailureHandler implements AuthenticationFailureHandler {
    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
        httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        httpServletResponse.setHeader("Access-Control-Allow-Credentials","true");
        // 设定类容为json的格式
        httpServletResponse.setContentType("application/json;charset=UTF-8");
        JsonMsg jsonMsg = new JsonMsg();
        jsonMsg.setCode(400);
        jsonMsg.setMsg("登录失败");
        httpServletResponse.getWriter().write(JSON.toJSONString(jsonMsg));
    }
}

EkAuthenticationSuccessHandler 认证成功配置类

@Component
public class EkAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
        httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        httpServletResponse.setHeader("Access-Control-Allow-Credentials","true");
        // 设定类容为json的格式
        httpServletResponse.setContentType("application/json;charset=UTF-8");
        JsonMsg jsonMsg = new JsonMsg();
        jsonMsg.setCode(200);
        jsonMsg.setMsg("登录成功");
        httpServletResponse.getWriter().write(JSON.toJSONString(jsonMsg));
    }
}

EkPasswordEncoder 密码加密配置类

@Component
public class EkPasswordEncoder implements PasswordEncoder {
    PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(14);
    @Override
    public String encode(CharSequence charSequence) {
        System.out.println(charSequence);
        System.out.println(passwordEncoder.encode(charSequence));
        return passwordEncoder.encode(charSequence);
    }
    @Override
    public boolean matches(CharSequence charSequence, String s) {
        System.out.println(String.format("charSequence=%s, s=%s", charSequence, s));
        System.out.println(String.format("passwordEncoder.matches=%s", passwordEncoder.matches(charSequence, s)));
        return passwordEncoder.matches(charSequence, s);
    }
}

到这里配置就算完成了,启动服务就可以看到效果了,没有登录的情况下访问permitAll()链接都会跳转到/index登录页,登录成功后再跳转。

二、JWT认证

我们只需要修改securityconfig配置类,并添加JWT配置即可其他不用修改

修改后的security配置类,我重新定义了个类,把注释去掉即可

package com.ek.security.config;

import com.ek.security.EkUserDetailsService;
import com.ek.security.handler.EkAuthenticationEntryPoint;
import com.ek.security.handler.EkAuthenticationFailureHandler;
import com.ek.security.handler.EkAuthenticationSuccessHandler;
import com.ek.security.jwt.EkJwtAuthorizationTokenFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * @ClassName: EkWebSecurityConfig
 * @Description: 前后端分离,后端security安全认证
 * @Author: edi_kai
 * @Date: 2019-08-06
 * @Version: V2.0
 **/

//@Configuration
//@EnableWebSecurity
//@EnableGlobalMethodSecurity(prePostEnabled = true)
public class EkApiSecurityConfig extends WebSecurityConfigurerAdapter {
//    @Autowired
//    private EkUserDetailsService userDetailsService;
//    @Autowired
//    private EkAuthenticationEntryPoint authenticationEntryPoint;
//    @Autowired
//    private EkAuthenticationFailureHandler authenticationFailureHandler;
//    @Autowired
//    private EkAuthenticationSuccessHandler authenticationSuccessHandler;
//    @Autowired
//    PasswordEncoder passwordEncoder;
//    @Autowired
//    EkJwtAuthorizationTokenFilter jwtAuthorizationTokenFilter;
//
//    @Override
//    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        // 添加自定义认证
//        auth
//            .userDetailsService(userDetailsService)
//            .passwordEncoder(passwordEncoder)
//        ;
//    }
//    @Override
//    protected void configure(HttpSecurity http) throws Exception {
////        http.authorizeRequests().antMatchers("/**").permitAll();
//        http.cors().and().csrf().disable()
////            .and()
//                .httpBasic().authenticationEntryPoint(authenticationEntryPoint)
//            .and()
//                .authorizeRequests()
//                .antMatchers("/", "/index", "/toLogin", "/fail", "/druid/**").permitAll()
//                .anyRequest().authenticated()
//    //            .access("@rbacauthorityservice.hasPermission(request,authentication)") // RBAC 动态 url 认证
//            .and()
//                .formLogin()//指定自己的登录页面
//                .failureHandler(authenticationFailureHandler)
//                .successHandler(authenticationSuccessHandler)
//            .and()
//                .logout()
//            .and()
//                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
//            .and()
//                .addFilterBefore(jwtAuthorizationTokenFilter, UsernamePasswordAuthenticationFilter.class)
//        ;
//    }
//
//    @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
//    @Override
//    public AuthenticationManager authenticationManagerBean() throws Exception {
//        return super.authenticationManagerBean();
//    }
}

JWT配置类

package com.ek.security.jwt;

import com.ek.security.EkUserDetails;
import com.ek.util.redis.EkRedisUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Clock;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.DefaultClock;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

/**
 * @ClassName: EkJwtTokenUtil
 * @Description: JWT工具类,配合Redis
 * @Author: qin_hqing
 * @Date: 2019-08-07
 * @Version: V2.0
 **/
@Component
public class EkJwtTokenUtil implements Serializable {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    private static final long serialVersionUID = -3301605591108950415L;
    // 权限缓存前缀
    private static final String REDIS_PREFIX_AUTH = "auth:";
    // 用户信息缓存前缀
    private static final String REDIS_PREFIX_USER = "user-details:";

    @Autowired
    private EkRedisUtil redisUtil;

    @Value("${jwt.secret}")
    private String secret;

    @Value("${jwt.expiration}")
    private Long expiration;

    @Value("${jwt.token_header}")
    private String tokenHeader;

    private Clock clock = DefaultClock.INSTANCE;

    /**
     * 生成token
     * @param userDetails
     * @return
     */
    public String generateToken(UserDetails userDetails) {
        EkUserDetails ekUserDetails = (EkUserDetails) userDetails;
        Map<String, Object> claims = new HashMap<>();
        String token = doGenerateToken(claims, ekUserDetails.getLoginName());
        String key = String.format("%s%s", REDIS_PREFIX_AUTH, ekUserDetails.getLoginName());
        redisUtil.set(key, token, expiration);
        return token;
    }

    private String doGenerateToken(Map<String, Object> claims, String subject) {
        final Date createdDate = clock.now();
        final Date expirationDate = calculateExpirationDate(createdDate);

        return Jwts.builder()
                .setClaims(claims)
                .setSubject(subject)
                .setIssuedAt(createdDate)
                .setExpiration(expirationDate)
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }

    private Date calculateExpirationDate(Date createdDate) {
        return new Date(createdDate.getTime() + expiration);
    }

    /**
     * 校验token是否合法
     * @param token
     * @return
     */
    public Boolean validateToken(String token) {
        final String logName = getUsernameFromToken(token);

        return StringUtils.isNotEmpty(token)
                && !isTokenExpired(token);

    }

    /**
     * 校验token是否合法
     * @param token
     * @param userDetails
     * @return
     */
    public Boolean validateToken(String token, UserDetails userDetails) {
        EkUserDetails user = (EkUserDetails) userDetails;
        final String logName = getUsernameFromToken(token);

        String key = String.format("%s%s", REDIS_PREFIX_AUTH, user.getLoginName());
        if (redisUtil.containsKey(key)){
            return StringUtils.isNotEmpty(token)
                    && token.equals(redisUtil.get(key))
                    && (logName.equals(user.getLoginName())
                    && !isTokenExpired(token));
        }

        return false;
    }

    /**
     * 根据token获取登录用户名
     * @param token
     * @return
     */
    public String getUsernameFromToken(String token) {
        return getClaimFromToken(token, Claims::getSubject);
    }

    public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = getAllClaimsFromToken(token);
        return claimsResolver.apply(claims);
    }

    private Claims getAllClaimsFromToken(String token) {
        return Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
    }

    private Boolean isTokenExpired(String token) {
        final Date expiration = getExpirationDateFromToken(token);
        return expiration.before(clock.now());
    }

    public Date getExpirationDateFromToken(String token) {
        return getClaimFromToken(token, Claims::getExpiration);
    }

    /**
     * 添加EkUserDetails缓存
     * @param userDetails
     */
    public void putUserDetails(UserDetails userDetails){
        EkUserDetails user = (EkUserDetails) userDetails;
        String key = String.format("%s%s", REDIS_PREFIX_USER, user.getLoginName());
        redisUtil.set(key, user, expiration);
    }

    /**
     * 根据token获取EkUserDetails
     * @param token
     * @return
     */
    public UserDetails getUserDetails(String token){
        String logName = getUsernameFromToken(token);
        String key = String.format("%s%s", REDIS_PREFIX_USER, logName);
        if (redisUtil.containsKey(key)){
            return redisUtil.get(key, EkUserDetails.class);
        }
        return null;
    }
}
package com.ek.security.jwt;

import com.ek.bean.base.EkUser;
import com.ek.security.EkUserDetails;
import com.ek.service.base.IEkUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
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;

/**
 * @ClassName: EkJwtAuthorizationTokenFilter
 * @Description: JWT拦截器,对token进行验证
 * @Author: qin_hqing
 * @Date: 2019-08-07
 * @Version: V2.0
 **/
@Component
public class EkJwtAuthorizationTokenFilter extends OncePerRequestFilter {

    @Value("${jwt.token_header}")
    private String EK_TOKEN_HEADER;
    @Value("${jwt.token_prefix}")
    private String EK_TOKEN_PREFIX;

    @Autowired
    private EkJwtTokenUtil jwtTokenUtil;
    @Autowired
    private IEkUserService userService;

    @Override
    protected void doFilterInternal(
            HttpServletRequest httpServletRequest,
            HttpServletResponse httpServletResponse,
            FilterChain filterChain) throws ServletException, IOException {

        String authHeader = httpServletRequest.getHeader(this.EK_TOKEN_HEADER);
        if (StringUtils.isNotEmpty(authHeader) && authHeader.startsWith(this.EK_TOKEN_PREFIX)){
            final String authToken = StringUtils.substring(authHeader, this.EK_TOKEN_PREFIX.length());
            String logName = StringUtils.isNoneEmpty(authToken) ? jwtTokenUtil.getUsernameFromToken(authToken) : null;

            if (StringUtils.isNotEmpty(logName) && SecurityContextHolder.getContext().getAuthentication() == null){
                EkUser user = userService.selectByLogName(logName);
                EkUserDetails userDetails = new EkUserDetails();
                userDetails.setPassword(user.getPassWord());
                userDetails.setLoginName(user.getLogName());
                userDetails.setUserName(user.getUserName());
                userDetails.setUserId(StringUtils.join(user.getId()));

                if (jwtTokenUtil.validateToken(authToken, userDetails)){
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                            userDetails,
                            null,
                            userDetails.getAuthorities()
                    );
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }
        }
        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }
}

三、在二的基础上只修改securityconfig配置类即可

package com.ek.security.config;

import com.ek.security.EkUserDetailsService;
import com.ek.security.handler.EkAuthenticationEntryPoint;
import com.ek.security.handler.EkAuthenticationFailureHandler;
import com.ek.security.handler.EkAuthenticationSuccessHandler;
import com.ek.security.handler.EkPasswordEncoder;
import com.ek.security.jwt.EkJwtAuthorizationTokenFilter;
import com.ek.security.jwt.EkJwtTokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
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.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@EnableWebSecurity
public class EkMultiSecurityConfig {
    @Autowired
    private EkUserDetailsService userDetailsService;
    @Autowired
    private EkAuthenticationEntryPoint authenticationEntryPoint;
    @Autowired
    private EkAuthenticationFailureHandler authenticationFailureHandler;
    @Autowired
    private EkAuthenticationSuccessHandler authenticationSuccessHandler;
    @Autowired
    private EkPasswordEncoder passwordEncoder;

    @Configuration
    @Order(1)
    public class ApiSecurityConfig extends WebSecurityConfigurerAdapter {

        @Autowired
        private EkJwtAuthorizationTokenFilter jwtAuthorizationTokenFilter;

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/api/**") //<= Security only available for /api/**
                    .authorizeRequests()
                    .antMatchers("/api/register").permitAll()
                    .antMatchers("/api/login").permitAll()
                    .antMatchers("/api/public").permitAll()
                    .antMatchers("/api/lost").permitAll()
                    .anyRequest().authenticated()
                .and()
                    .formLogin()
                    .failureHandler(authenticationFailureHandler)
                .and()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                    .addFilterBefore(jwtAuthorizationTokenFilter, UsernamePasswordAuthenticationFilter.class)
            ;
        }
    }

    @Configuration
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            // 添加自定义认证
            auth
                    .userDetailsService(userDetailsService)
                    .passwordEncoder(passwordEncoder)
            ;
        }
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            //        http.authorizeRequests().antMatchers("/**").permitAll();
            http.csrf().disable()
//                .and()
                    .httpBasic().authenticationEntryPoint(authenticationEntryPoint)
                .and()
                    .authorizeRequests()
                    .antMatchers("/", "/index", "/toLogin", "/fail", "/druid/**").permitAll()
                    .antMatchers("/resources/**").permitAll()
                    .anyRequest().authenticated()
                    //            .access("@rbacauthorityservice.hasPermission(request,authentication)") // RBAC 动态 url 认证
                .and()
                    .formLogin().loginPage("/index") //指定自己的登录页面
                    .loginProcessingUrl("/toLogin")
                    .usernameParameter("logName")
                    .passwordParameter("password")
                    .defaultSuccessUrl("/success", false)
                    .failureHandler(authenticationFailureHandler)
//                .successHandler(authenticationSuccessHandler)
                .and()
                    .logout()
            ;
        }
    }
}

用到的其他类

@RestController
@RequestMapping("/users")
public class EkUserController {
    private Logger log = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private IEkUserService ekUserService;
    @RequestMapping(value = "", method = RequestMethod.GET)
    public JsonMsg getEkUserList(){
        log.info("--------------------列表--------------------------------");
        JsonMsg jsonMsg = new JsonMsg();
        List<EkUser> list = ekUserService.selectUserList(new HashMap<>());
        jsonMsg.setCode(200);
        jsonMsg.setMsg("success");
        jsonMsg.setData(list);
        return jsonMsg;
    }
}
@RestController
public class LoginController {
    private Logger log = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private IEkUserService ekUserService;
    @RequestMapping(value = {"", "/index"})
    public ModelAndView index(){
        log.info("--------------------首页--------------------------------");
        return new ModelAndView("index");
    }
    @RequestMapping(value = "/fail")
    public ModelAndView fail(){
        log.info("--------------------fail--------------------------------");
        return new ModelAndView("fail");
    }
    @RequestMapping(value = "/toLogin", method = RequestMethod.POST)
    public ModelAndView toLogin(){
        log.info("--------------------toLogin--------------------------------");
        return new ModelAndView("success");
    }

    @RequestMapping(value = "/success")
    public ModelAndView success(){
        log.info("--------------------success--------------------------------");
        return new ModelAndView("success");
    }
}

说明:

  关于druid监控登录的问题,我把它放到了下面这个地方,网上查资料说是添加http.csrf().ignoringAntMatchers("/druid/*")就行,但是我添加后并没有成功。

.antMatchers("/", "/index", "/toLogin", "/fail", "/druid/**").permitAll()

 

posted on 2019-08-08 09:35  汉有游女,君子于役  阅读(1730)  评论(0编辑  收藏  举报