中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

vue2+springsecurity權限系統怎么實現

發布時間:2023-05-04 14:48:44 來源:億速云 閱讀:101 作者:iii 欄目:開發技術

本篇內容介紹了“vue2+springsecurity權限系統怎么實現”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

準備內容

新建項目,SpringBoot采用2.7.11,spring-boot-starter-security,vue 2.0

默認會自動啟動攔截裝置,可以這樣取消,先這樣配置一下

@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})

JWT 校驗用戶的憑證(頭部,載荷,簽證)

引入依賴

<!-- JWT -->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.2.0</version>
</dependency>

邏輯:用戶登錄后,請求頭中加一個token參數,如果有則表示可以訪問,沒有就不能訪問,這是一個小測試還是有點缺陷的

SpringSecurity 權限控制

一共有兩個最主要攔截器

  • 登陸驗證攔截器AuthenticationProcessingFilter

  • 資源管理攔截器AbstractSecurityInterceptor

但攔截器里面的實現需要一些組件來實現分別是

  • AuthenticationManager認證管理器

  • accessDecisionManager決策管理器等組件來支撐。

流程圖解讀:

  • 用戶提交用戶名、密碼被SecurityFilterChain中的 UsernamePasswordAuthenticationFilter 過濾器獲取到,封裝為請求Authentication,通常情況下是UsernamePasswordAuthenticationToken這個實 現類。

  • 然后過濾器將Authentication提交至認證管理器(AuthenticationManager)進行認證 。

  • 認證成功后, AuthenticationManager 身份管理器返回一個被填充滿了信息的(包括上面提到的權 限信息, 身份信息,細節信息,但密碼通常會被移除) Authentication 實例。

  • SecurityContextHolder 安全上下文容器將第3步填充了信息的 Authentication
    通過 SecurityContextHolder.getContext().setAuthentication(&hellip;)方法,設置到其中。 可以看出 AuthenticationManager接口(認證管理器)是認證相關的核心接口,也是發起認證的出發點,它的實 現類為ProviderManager。而Spring Security支持多種認證方式,因此ProviderManager維護著一個 List 列表,存放多種認證方式,最終實際的認證工作是由 AuthenticationProvider完成的。咱們知道 web表單的對應的AuthenticationProvider實現類為 DaoAuthenticationProvider,它的內部又維護著 一個UserDetailsService負責UserDetails的獲取。最終 AuthenticationProvider將UserDetails填充至 Authentication。

現在關掉之前的SecurityAutoConfiguration.class,打開是不是直接跳轉到了登錄頁面呢,無法訪問接口了

配置 SpringSecurity

先說下創建token的工具類

/**
 * 簽發JWT
 *
 * @param id 用戶ID
 * @param subject   可以是JSON數據 盡可能少
 * @param ttlMillis 不知道
 * @return 結果
 */
public static String createJWT(String id, String subject, long ttlMillis) {
    SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
    // 獲取當前時間毫秒
    long nowMillis = System.currentTimeMillis();
    // 獲取當前時間日期類型
    Date now = new Date(nowMillis);
    // 生成一個加密的key
    SecretKey secretKey = generalKey();
    JwtBuilder builder = Jwts.builder()
            .setId(id)
            .setSubject(subject)   // 主題
            .setIssuer("ChiHaiKeJi2016")     // 簽發者
            .setIssuedAt(now)   // 簽發時間
            .signWith(signatureAlgorithm, secretKey); // 簽名算法以及密匙
    if (ttlMillis >= 0) {
        long expMillis = nowMillis + ttlMillis;
        Date expDate = new Date(expMillis);
        builder.setExpiration(expDate); // 過期時間
    }
    return builder.compact();
}
/**
 * 生成jwt token
 * @param username 用戶名
 */
public static String genJwtToken(String username) {
    return createJWT(username, username, 60 * 60 * 1000);
}
/**
 * 生成加密Key
 */
public static SecretKey generalKey() {
    // 目前只知道這個方法生成一個key,并用base64解碼
    byte[] encodedKey = Base64.decode(JwtConstant.JWT_SECERT);
    // 目前不知道啥意思
    return new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
}

配置信息--新建SecurityConfig

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
    // 白名單
    private static final String[] URL_WHITE_LIST = {"/login"};
    @Resource
    private LoginHandler loginHandler;
    // 密碼加密方式
    @Bean
    protected PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    @Bean
    protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
        // 開啟跨域 以及csrf攻擊關閉
        httpSecurity.cors().and().csrf().disable()
                // 登錄登出配置
                .formLogin()
                // 登錄成功接口
                .successHandler(loginHandler)
                // 登錄失敗的接口
                .failureHandler(loginHandler)
//                .and().logout().logoutSuccessHandler()
                // session禁用配置
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 無狀態,前后端分離
                // 攔截規則配置 // // 白名單內容放行
                .and().authorizeRequests().antMatchers(URL_WHITE_LIST).permitAll()
                // 需要認證
                .anyRequest().authenticated();
        return httpSecurity.build();
    }
}

配置登錄失敗與成功接口---新建---LoginHandler 處理類

/**
 * 登錄成功與失敗處理器
 */
@Component
public class LoginHandler implements AuthenticationSuccessHandler, AuthenticationFailureHandler {
    // 登錄成功的
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        ServletOutputStream stream = response.getOutputStream();
        // 獲取token
        String token = JwtUtils.genJwtToken("user");
        // 寫入數據
        stream.write(JSONUtil.toJsonStr(new Result("登錄成功", token)).getBytes());
        stream.flush();
        stream.close();
    }
    // 登錄失敗的
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        ServletOutputStream stream = response.getOutputStream();
        String message = exception.getMessage();
        if (exception instanceof BadCredentialsException) {
            message = "用戶名或者密碼錯誤!";
        }
        stream.write(JSONUtil.toJsonStr(new Result(message)).getBytes(StandardCharsets.UTF_8));
        stream.flush();
        stream.close();
    }
}

在用戶service實現類中自定義查詢數據庫

@Service
public class SysUserServiceImpl implements SysUserService, UserDetailsService {
    @Resource
    private SysUserMapper sysUserMapper;
    // 自定義查詢參數是用戶名
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        LambdaQueryWrapper<SysUser> sysUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysUserLambdaQueryWrapper.eq(SysUser::getUsername, username);
        SysUser user = sysUserMapper.selectOne(sysUserLambdaQueryWrapper);
        if (user == null) {
            throw new UsernameNotFoundException("用戶名或密碼錯誤!");
        } else if ("1".equals(user.getStatus())) {
            throw new UsernameNotFoundException("該用戶已被封禁!");
        }
        // 第三個是擁有權限
        return new User(user.getUsername(), user.getPassword(), getUserAuthority());
    }
    // 權限
    private List<GrantedAuthority> getUserAuthority() {
        return new ArrayList<>();
    }
}

再來說下前端,先配置跨域

module.exports = {
  devServer: {
    host: '0.0.0.0', // 可以忽略不寫
    port: 8080, // 它是用來修改你打開后的端口號的
    open: true, // 值為 true的話,項目啟動時自動打開到瀏覽器里邊, false不會打開
    proxy: {
      '/api': {
        target: 'http://localhost:82', // 跨域請求的公共地址
        ws: false, // 也可以忽略不寫,不寫不會影響跨域
        changeOrigin: true, // 是否開啟跨域,值為 true 就是開啟, false 不開啟
        pathRewrite: {
          '^/api': ''// 注冊全局路徑, 但是在你請求的時候前面需要加上 /api
        }
      }
    }
  }
}

配置axios,因為配置了跨域,這個時候可以直接寫api了

import axios from 'axios'
const request = axios.create({
  baseURL: '/api' // 因為配置跨域了
})
// 下面這是攔截器,攔截請求,自動加token令牌
request.interceptors.request.use(
  config => {
    config.headers.token = `${localStorage.getItem('token')}`
    return config
  }
)
export default request

說下如何請求前端登錄接口POST請求
    登錄接口就是login,傳入username和password就可以了

export const Login = function (data) {
  return request({
    method: 'post',
    url: 'login',
    data: qs.stringify(data)
  })
}

“vue2+springsecurity權限系統怎么實現”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

贵州省| 鸡东县| 鸡西市| 麻城市| 桐柏县| 柳河县| 安西县| 讷河市| 泸水县| 科技| 兰州市| 合山市| 秦安县| 普兰店市| 孟津县| 渝中区| 鄂温| 邢台县| 开平市| 西青区| 伊金霍洛旗| 新泰市| 海阳市| 铜山县| 公主岭市| 九台市| 桃园县| 宁强县| 茂名市| 锡林浩特市| 华坪县| 利津县| 庆阳市| 惠安县| 白水县| 青州市| 甘德县| 西丰县| 荥经县| 昔阳县| 嫩江县|