1. 程式人生 > >spring-boot整合spring-security實現簡單登入(ajax登入實現)

spring-boot整合spring-security實現簡單登入(ajax登入實現)

平常再做一些專案時,有些專案並不需要複雜的登入許可權驗證 只需要簡單登入許可權驗證(保證安全可靠的前提下),找來找去只有spring-security最適合不過了,在spring-boot下配置簡單 便捷 快速 能滿足基本的登入許可權控制需求。

第一步:引入spring-security maven依賴

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

第二步:編寫spring-security配置類 WebSecurityConfig

package com.xcloud.currency.config;

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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.web.filter.CharacterEncodingFilter;

/**
 * Xcloud-Api By IDEA
 * Created by LaoWang on 2018/8/28.
 * WebSecurityConfigurerAdapter:重寫它的方法來設定一些web的安全
 */
@Configuration
@EnableWebSecurity // 註解開啟Spring Security的功能
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    MyAuthenctiationFailureHandler myAuthenctiationFailureHandler;

    @Autowired
    MyAuthenctiationSuccessHandler myAuthenctiationSuccessHandler;

    @Override
    public void configure(WebSecurity web) throws Exception {
        //解決靜態資源被攔截的問題
        web.ignoring().antMatchers("/css/**");
        web.ignoring().antMatchers("/js/**");
        web.ignoring().antMatchers("/images/**");
        web.ignoring().antMatchers("/lib/**");
        web.ignoring().antMatchers("/fonts/**");
        web.ignoring().antMatchers("/lang/**");
        web.ignoring().antMatchers("/login/**");
        web.ignoring().antMatchers("/login.html");
        //解決服務註冊url被攔截的問題
        web.ignoring().antMatchers("/swagger-resources/**");
        web.ignoring().antMatchers("/v2/**");
        web.ignoring().antMatchers("/**/*.json");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .failureHandler(myAuthenctiationFailureHandler) // 自定義登入失敗處理
                .successHandler(myAuthenctiationSuccessHandler) // 自定義登入成功處理
                .and()
                .authorizeRequests()  //定義哪些url需要保護,哪些url不需要保護
                .anyRequest().authenticated()
                .and()
                .sessionManagement().maximumSessions(1)
                .and()
                .and()
                .logout()
                .logoutUrl("/logout")
                .and()
                .formLogin()
                .loginPage("/login.html")  //定義當需要使用者登入時候,轉到的登入頁面
                .loginProcessingUrl("/meureka/login")  // 自定義的登入介面
                .permitAll()
                .defaultSuccessUrl("/index.html").permitAll()
                .and()
                .logout()
                .permitAll()
                // 自動登入
                .and().rememberMe();
        http.csrf().disable();
        //解決中文亂碼問題
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("UTF-8");
        filter.setForceEncoding(true);
        http.addFilterBefore(filter,CsrfFilter.class);
    }
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("admin")
            .password("12345678")
            .roles("USER");
        //在記憶體中建立了一個使用者,該使用者的名稱為user,密碼為password,使用者角色為USER
    }
}

在這裡我使用了spring-security自定義處理器 來處理登入失敗和登陸成功的邏輯,方便前臺ajax呼叫做相關處理業務

登入介面可以使用自己個性化的登入模板,

web.ignoring().antMatchers("/css/**");根據自己的專案進行配置 哪些不需要被攔截的url可以用這個來配置
配置登入賬號密碼  可以配置多個
auth.inMemoryAuthentication()
    .withUser("admin")
    .password("12345678")
    .roles("USER");

自定義配置項(根據自己專案配置)

第三步:自定義登入失敗處理器  MyAuthenctiationFailureHandler

package com.xcloud.currency.config;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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 {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
                                        AuthenticationException exception) throws IOException, ServletException {
        log.info("登入失敗");
        JSONObject res = new JSONObject();
        res.put("success",false);
        res.put("msg","登入失敗,請檢查賬號密碼是否正確");
        response.setStatus(500);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().append(res.toString());
    }
}

第四步:自定義登入成功處理器  MyAuthenctiationSuccessHandler

package com.xcloud.currency.config;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
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 {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
        log.info("登入成功");
        JSONObject res = new JSONObject();
        res.put("success",true);
        res.put("msg","登入成功");
        response.setStatus(200);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().append(res.toString());
    }
}

登入頁面上呼叫(普通表單形式)

ajax呼叫

function login() {
        var username = $("#username").val();
        var password = $("#password").val();
        if (username == "" || password == "") {
            layer.msg('使用者名稱或密碼不能為空', {icon: 2});
            return;
        }
        $.ajax({
            type: "POST",
            url: "meureka/login",
            data: {
                "username": username,
                "password": password
            },
            success: function (e) {
                layer.msg(e.msg, {icon: 1});
                setTimeout(function () {
                    location.href = 'index.html';
                }, 1500);
            },
            error: function (e) {
                console.log(e.responseText);
                layer.msg(JSON.parse(e.responseText).msg, {icon: 2});
            }
        });
    }