SpringSecurity自定义 配置类

  • Post author:
  • Post category:其他


SpringSecurity自定义 配置类

在项目中有可能需要使用SpringSecurity来进行项目权限的管理,可以使用配置类的形式进行SpringSecutiry的配置

import com.example.demo.security.MyAuthenctiationFailureHandler;
import com.example.demo.security.MyAuthenctiationSuccessHandler;
import com.example.demo.security.MyUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

@Component
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyUserDetailsService myUserDetailsService;//自己定义的查询方法

    @Autowired
    private PasswordEncoder passwordEncoder;//springsecurity自带的加密密码的方法

    @Autowired
    private MyAuthenctiationSuccessHandler myAuthenctiationSuccessHandler;//登录成功回调

    @Autowired
    private MyAuthenctiationFailureHandler myAuthenctiationFailureHandler;//登录失败回调

    /**
     * 用户授权
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //使用自定义认证类实现授权
        auth.userDetailsService(myUserDetailsService).passwordEncoder(passwordEncoder);
    }

    /**
     * 配置放行的请求
     * @param web
     * @throws Exception
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/css/**");
        web.ignoring().antMatchers("/js/**");
        web.ignoring().antMatchers("/img/**");
        web.ignoring().antMatchers("/plugins/**");
        web.ignoring().antMatchers("/login.html");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //其他任何路径都需要管理员登录
        http.authorizeRequests()
                .antMatchers("/**")
                .access("hasRole('admin')");

        //登录相关配置
        http.formLogin()
                .loginPage("/login.html")//指定登录地址
                .loginProcessingUrl("/login")//指定处理登录请求地址
                .successHandler(myAuthenctiationSuccessHandler)
                .failureHandler(myAuthenctiationFailureHandler);

        //登出相关配置
        http.logout()
                .logoutUrl("/logout")
                .invalidateHttpSession(true);//注销session

        //设置用户只允许在一处登录,在其他地方登录则挤掉已登录用户,被挤掉的用户则返回log.html
        http.sessionManagement().maximumSessions(1).expiredUrl("/login.html");

        //关闭csrf安全策略
        http.csrf().disable();

        //允许跳转显示iframe
        http.headers().frameOptions().disable();

        //异常处理页面,例如没有权限访问等
        http.exceptionHandling().accessDeniedPage("/error.html");
    }
}

自定义的MyUserDetailsService

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
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;

import java.util.ArrayList;

@Component
@Slf4j
public class MyUserDetailsService implements UserDetailsService {
    private Logger log = LoggerFactory.getLogger(MyUserDetailsService.class);

    @Autowired
    private UserService userService;//自己写数据库查询用户信息的UserService

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userService.findOneUserByName(username);//UserService类中的方法
        if (user == null){
            return null;
        }
        log.info("user=={}",user);
        ArrayList<GrantedAuthority> authority = new ArrayList<>();
        authority.add(new SimpleGrantedAuthority("role_manager"));
        return new User(user.getUsername(),user.getPassword(),authority);
    }
}

登录成功回调MyAuthenctiationSuccessHandler

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

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

@Slf4j
@Component("MyAuthenctiationSuccessHandler")
public class MyAuthenctiationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
    private Logger log = LoggerFactory.getLogger(MyAuthenctiationSuccessHandler.class);

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private UserService userService;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        log.info("***********登录成功***********");
        String name = SecurityContextHolder.getContext().getAuthentication().getName();
        log.info("name"+name);
        User user = userService.findOneUserByName(name);
        request.getSession().setAttribute("userid",user.getId());
        Result result = new Result(200,"登录成功");//自定义的返回类

        response.setContentType("application/json;chatset=UTF-8");
        response.getWriter().write(objectMapper.writeValueAsString(result));
    }
}

登录失败回调MyAuthenctiationFailureHandler

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;

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

@Slf4j
@Component("MyAuthenctiationFailureHandler")
public class MyAuthenctiationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
    private Logger log = LoggerFactory.getLogger(MyAuthenctiationFailureHandler.class);

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        log.error("***********登录失败***********");
        response.setStatus(HttpStatus.FORBIDDEN.value());

        //登录失败信息
        Result result = new Result(403,"账号或者密码不正确");
        response.getWriter().write(objectMapper.writeValueAsString(result));
    }
}



版权声明:本文为invincible_yj原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。