Spring Security前后端分离实现

自定义UsernamePasswordAuthenticationFilter

package com.monkeylessey.xp;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * @author xp
 * @version 1.0
 * @date 2022/3/31 0031 17:13
 */
public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        // post请求
        if (!request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }

        if (request.getContentType().equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE)) {
            try {
                Map<String, Object> map = new ObjectMapper().readValue(request.getInputStream(), Map.class);
                String username = (String) map.get(getUsernameParameter());
                String password = (String) map.get(getPasswordParameter());

                username = (username != null) ? username : "";
                username = username.trim();
                password = (password != null) ? password : "";
                UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
                // Allow subclasses to set the "details" property
                setDetails(request, token);
                return this.getAuthenticationManager().authenticate(token);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return super.attemptAuthentication(request,response);
    }
}

Security配置类:

package com.monkeylessey.xp.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.monkeylessey.xp.MyUsernamePasswordAuthenticationFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationManager;
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.core.Authentication;
import org.springframework.security.core.AuthenticationException;
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.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

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

/**
 * @author xp
 * @version 1.0
 * @date 2022/3/31 0031 17:52
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public UserDetailsService getUserDetails() {
        InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
        inMemoryUserDetailsManager.createUser(User.withUsername("xp").password("{noop}666").roles("admin").build());
        return inMemoryUserDetailsManager;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(getUserDetails());
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    /**
     * 自定义认证过滤器
     * @return
     * @throws Exception
     */
    @Bean
    public MyUsernamePasswordAuthenticationFilter get() throws Exception {
        MyUsernamePasswordAuthenticationFilter myLoginFilter = new MyUsernamePasswordAuthenticationFilter();
        myLoginFilter.setUsernameParameter("u");
        myLoginFilter.setPasswordParameter("p");
        myLoginFilter.setFilterProcessesUrl("/xplogin"); // 指定认证的请求
        myLoginFilter.setAuthenticationManager(authenticationManagerBean());
        myLoginFilter.setAuthenticationFailureHandler(new AuthenticationFailureHandler() {
            @Override
            public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
                Map<String,Object> map = new HashMap<>();
                map.put("msg", "登录成功");
                String s = new ObjectMapper().writeValueAsString(map);
                response.getWriter().print(s);

                response.setContentType("application/json;charset=UTF-8");
                response.setStatus(HttpStatus.OK.value());
                System.out.println("认证失败");
            }
        });
        myLoginFilter.setAuthenticationSuccessHandler(new AuthenticationSuccessHandler() {
            @Override
            public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                Map<String,Object> map = new HashMap<>();
                map.put("msg", "登录失败");
                String s = new ObjectMapper().writeValueAsString(map);
                response.getWriter().print(s);

                response.setContentType("application/json;charset=UTF-8");
                response.setStatus(HttpStatus.FORBIDDEN.value());
                System.out.println("认证失败");
            }
        });
        return myLoginFilter;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin();

        http.authorizeRequests()
                .anyRequest().authenticated();

        http.csrf().disable();

        // at是用filter去替换某个filter
        http.addFilterAt(get(), UsernamePasswordAuthenticationFilter.class);

    }
}

测试接口

package com.monkeylessey.xp.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author xp
 * @version 1.0
 * @date 2022/3/31 0031 15:06
 */
@RestController
@RequestMapping
public class TestController {

    @GetMapping("/one")
    public String testA() {
        return "小老弟你来啦";
    }
}

随手一个依赖吧

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-securityartifactId>
dependency>
<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-webartifactId>
dependency>

原理待更新。。。

你可能感兴趣的:(Spring,Security,spring,security,spring,boot,前后端分离)