ylbtech-Java-Class-@I:java.annotation.Resource
1.返回顶部
 
2.返回顶部
1.1、
import javax.annotation.Resource;
1.2、
package com.ylbtech.api.platform.controller.auth;

import com.ylbtech.api.platform.core.jwt.JwtConfigurationProperties;
import com.ylbtech.api.platform.core.jwt.JwtUtil;
import com.ylbtech.api.platform.core.response.Result;
import com.ylbtech.api.platform.core.response.ResultGenerator;
import com.ylbtech.edu.organization.domain.Organization;
import com.ylbtech.edu.organization.service.IOrganizationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; @Slf4j
@Api(value = "账户接口")
@Validated
@RestController
@RequestMapping("/user")
public class AuthController { @Resource
private JwtUtil jwtUtil; @Autowired
private IOrganizationService organizationService; /**
* showdoc
* @catalog 用户
* @title 账户注销
* @description 账户注销接口
* @method Delete
* @url https://ip:port/user/token/logout
* @param adminID 必选 string 账号
* @return {"code":200}
* @remark
*/
@ApiOperation(value = "账户注销")
@PostMapping("/token/logout")
public Result logout(@ApiParam(required = true) @RequestBody OrganizationAdmin organizationAdmin) { if (organizationAdmin.getAdminID() == null || organizationAdmin.getAdminID().equalsIgnoreCase("")) {
return ResultGenerator.genFailedResult("adminID is null");
}
this.jwtUtil.invalidRedisToken(organizationAdmin.getAdminID());
return ResultGenerator.genOkResult();
}
}
1.3、
3.返回顶部
 
4.返回顶部
1、
/*
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/ package javax.annotation; import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*; /**
* The Resource annotation marks a resource that is needed
* by the application. This annotation may be applied to an
* application component class, or to fields or methods of the
* component class. When the annotation is applied to a
* field or method, the container will inject an instance
* of the requested resource into the application component
* when the component is initialized. If the annotation is
* applied to the component class, the annotation declares a
* resource that the application will look up at runtime. <p>
*
* Even though this annotation is not marked Inherited, deployment
* tools are required to examine all superclasses of any component
* class to discover all uses of this annotation in all superclasses.
* All such annotation instances specify resources that are needed
* by the application component. Note that this annotation may
* appear on private fields and methods of superclasses; the container
* is required to perform injection in these cases as well.
*
* @since Common Annotations 1.0
*/
@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface Resource {
/**
* The JNDI name of the resource. For field annotations,
* the default is the field name. For method annotations,
* the default is the JavaBeans property name corresponding
* to the method. For class annotations, there is no default
* and this must be specified.
*/
String name() default ""; /**
* The name of the resource that the reference points to. It can
* link to any compatible resource using the global JNDI names.
*
* @since Common Annotations 1.1
*/ String lookup() default ""; /**
* The Java type of the resource. For field annotations,
* the default is the type of the field. For method annotations,
* the default is the type of the JavaBeans property.
* For class annotations, there is no default and this must be
* specified.
*/
Class<?> type() default java.lang.Object.class; /**
* The two possible authentication types for a resource.
*/
enum AuthenticationType {
CONTAINER,
APPLICATION
} /**
* The authentication type to use for this resource.
* This may be specified for resources representing a
* connection factory of any supported type, and must
* not be specified for resources of other types.
*/
AuthenticationType authenticationType() default AuthenticationType.CONTAINER; /**
* Indicates whether this resource can be shared between
* this component and other components.
* This may be specified for resources representing a
* connection factory of any supported type, and must
* not be specified for resources of other types.
*/
boolean shareable() default true; /**
* A product specific name that this resource should be mapped to.
* The name of this resource, as defined by the <code>name</code>
* element or defaulted, is a name that is local to the application
* component using the resource. (It's a name in the JNDI
* <code>java:comp/env</code> namespace.) Many application servers
* provide a way to map these local names to names of resources
* known to the application server. This mapped name is often a
* <i>global</i> JNDI name, but may be a name of any form. <p>
*
* Application servers are not required to support any particular
* form or type of mapped name, nor the ability to use mapped names.
* The mapped name is product-dependent and often installation-dependent.
* No use of a mapped name is portable.
*/
String mappedName() default ""; /**
* Description of this resource. The description is expected
* to be in the default language of the system on which the
* application is deployed. The description can be presented
* to the Deployer to help in choosing the correct resource.
*/
String description() default "";
}
2、
5.返回顶部
1、JwtUtil.java
package com.ylbtech.api.platform.core.jwt;

import com.ylbtech.api.platform.core.rsa.RsaUtils;
import com.ylbtech.api.platform.util.RedisUtils;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.Duration;
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collectors; /**
* Json web token 工具 验证、生成 token
*/
@Slf4j
@Component
public class JwtUtil {
@Resource
private RedisUtils redisUtils;
@Resource
private RsaUtils rsaUtils;
@Resource
private JwtConfigurationProperties jwtProperties; private Claims getClaims(final String token) {
final Jws<Claims> jws = this.parseToken(token);
return jws == null ? null : jws.getBody();
} /**
* 根据 token 得到账户名
*/
public String getName(final String token) {
final Claims claims = this.getClaims(token);
return claims == null ? null : claims.getSubject();
} /**
* 签发 token
*
* @param name 账户名
* @param grantedAuthorities 账户权限信息[ADMIN, TEST, ...]
*/
public String sign(
final String name, final Collection<? extends GrantedAuthority> grantedAuthorities) {
// 函数式创建 token,避免重复书写
final Supplier<String> createToken = () -> this.createToken(name, grantedAuthorities);
// 看看缓存有没有账户token
final String token = (String) this.redisUtils.getValue(name);
// 没有登录过
if (StringUtils.isBlank(token)) {
return createToken.get();
}
final boolean isValidate = (boolean) this.redisUtils.getValue(token);
// 有 token,仍有效,将 token 置为无效,并重新签发(防止 token 被利用)
if (isValidate) {
this.invalidRedisToken(name);
}
// 重新签发
return createToken.get();
} /**
* 清除账户在 Redis 中缓存的 token
*
* @param name 账户名
*/
public void invalidRedisToken(final String name) {
// 将 token 设置为无效
final String token = (String) this.redisUtils.getValue(name);
Optional.ofNullable(token).ifPresent(_token -> this.redisUtils.setValue(_token, false));
} /**
* 从请求头或请求参数中获取 token
*/
public String getTokenFromRequest(final HttpServletRequest httpRequest) {
final String header = this.jwtProperties.getHeader();
final String token = httpRequest.getHeader(header);
return StringUtils.isNotBlank(token) ? token : httpRequest.getParameter(header);
} /**
* 返回账户认证
*/
public UsernamePasswordAuthenticationToken getAuthentication(
final String name, final String token) {
// 解析 token 的 payload
final Claims claims = this.getClaims(token);
// 因为 JwtAuthenticationFilter 拦截器已经检查过 token 有效,所以可以忽略 get 空指针提示
assert claims != null;
final String claimKeyAuth = this.jwtProperties.getClaimKeyAuth();
// 账户角色列表
final List<String> authList = Arrays.asList(claims.get(claimKeyAuth).toString().split(","));
// 将元素转换为 GrantedAuthority 接口集合
final Collection<? extends GrantedAuthority> authorities =
authList.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList());
final User user = new User(name, "", authorities);
return new UsernamePasswordAuthenticationToken(user, null, authorities);
} /**
* 验证 token 是否正确
*/
public boolean validateToken(final String token) {
boolean isValidate = true;
final Object redisTokenValidate = this.redisUtils.getValue(token);
// 可能 redis 部署出现了问题
// 或者清空了缓存导致 token 键不存在
if (redisTokenValidate != null) {
isValidate = (boolean) redisTokenValidate;
}
// 能正确解析 token,并且 redis 中缓存的 token 也是有效的
return this.parseToken(token) != null && isValidate;
} /**
* 生成 token
*/
private String createToken(
final String name, final Collection<? extends GrantedAuthority> grantedAuthorities) {
// 获取账户的角色字符串,如 USER,ADMIN
final String authorities =
grantedAuthorities
.stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.joining(","));
log.debug("==> user<{}> authorities: {}", name, authorities); // 过期时间
final Duration expireTime = this.jwtProperties.getExpireTime();
// 当前时间 + 有效时长
final Date expireDate = new Date(System.currentTimeMillis() + expireTime.toMillis());
// 创建 token,比如 "Bearer abc1234"
final String token =
this.jwtProperties.getTokenType()
+ " "
+ Jwts.builder()
// 设置账户名
.setSubject(name)
// 添加权限属性
.claim(this.jwtProperties.getClaimKeyAuth(), authorities)
// 设置失效时间
.setExpiration(expireDate)
// 私钥加密生成签名
.signWith(SignatureAlgorithm.RS256, this.rsaUtils.loadPrivateKey())
// 使用LZ77算法与哈夫曼编码结合的压缩算法进行压缩
.compressWith(CompressionCodecs.DEFLATE)
.compact();
// 保存账户 token
// 因为账户注销后 JWT 本身只要没过期就仍然有效,所以只能通过 redis 缓存来校验有无效
// 校验时只要 redis 中的 token 无效即可(JWT 本身可以校验有无过期,而 redis 过期即被删除了)
// true 有效
this.redisUtils.setValue(token, true, expireTime);
// redis 过期时间和 JWT 的一致
this.redisUtils.setValue(name, token, expireTime);
log.debug("==> Redis set uid<{}> token: {}", name, token);
return token;
} /**
* 解析 token
*/
private Jws<Claims> parseToken(final String token) {
try {
return Jwts.parser()
// 公钥解密
.setSigningKey(this.rsaUtils.loadPublicKey())
.parseClaimsJws(token.replace(this.jwtProperties.getTokenType(), ""));
} catch (final SignatureException e) {
// 签名异常
log.debug("Invalid JWT signature");
} catch (final MalformedJwtException e) {
// 格式错误
log.debug("Invalid JWT token");
} catch (final ExpiredJwtException e) {
// 过期
log.debug("Expired JWT token");
} catch (final UnsupportedJwtException e) {
// 不支持该JWT
log.debug("Unsupported JWT token");
} catch (final IllegalArgumentException e) {
// 参数错误异常
log.debug("JWT token compact of handler are invalid");
}
return null;
}
}

JwtUtil.java

2、
 
6.返回顶部
 
作者:ylbtech
出处:http://ylbtech.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

Java-Class-@I:java.annotation.Resource的更多相关文章

  1. Java总结篇:Java多线程

    Java总结篇系列:Java多线程 多线程作为Java中很重要的一个知识点,在此还是有必要总结一下的. 一.线程的生命周期及五种基本状态 关于Java中线程的生命周期,首先看一下下面这张较为经典的图: ...

  2. 转 Java虚拟机5:Java垃圾回收(GC)机制详解

    转 Java虚拟机5:Java垃圾回收(GC)机制详解 Java虚拟机5:Java垃圾回收(GC)机制详解 哪些内存需要回收? 哪些内存需要回收是垃圾回收机制第一个要考虑的问题,所谓“要回收的垃圾”无 ...

  3. Java并发编程:Java的四种线程池的使用,以及自定义线程工厂

    目录 引言 四种线程池 newCachedThreadPool:可缓存的线程池 newFixedThreadPool:定长线程池 newSingleThreadExecutor:单线程线程池 newS ...

  4. Java虚拟机2:Java内存区域

    1.几个计算机的概念 为以后写文章考虑,也为巩固自己的知识和一些基本概念,这里要理清楚几个计算机中的概念. 1.计算机存储单位 从小到大依次为位Bit.字节Byte.千字节KB.兆M.千兆GB.TB, ...

  5. Java调用本地接口:java.lang.UnsatisfiedLinkError

    Java调用本地接口:java.lang.UnsatisfiedLinkError 我的问题不在这篇文章描述中, 而是因为jni原来是c实现, 现在切换到cpp了, 需要在对应的cpp文件中加入ext ...

  6. Java基础16:Java多线程基础最全总结

    Java基础16:Java多线程基础最全总结 Java中的线程 Java之父对线程的定义是: 线程是一个独立执行的调用序列,同一个进程的线程在同一时刻共享一些系统资源(比如文件句柄等)也能访问同一个进 ...

  7. Java基础教程:Java内存区域

    Java基础教程:Java内存区域 运行时数据区域 Java虚拟机在执行Java程序的过程种会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟 ...

  8. jsp(java server pages):java服务器端的页面

    jsp(java server pages):java服务器端的页面 JSP的执行过程1.浏览器输入一个jsp页面2.tomcat会接受*.jsp请求,将该请求发送到org.apache.jasper ...

  9. JAVA基础语法:java编程规范和常用数据类型(转载)

    JAVA基础语法:java编程规范和常用数据类型 摘要 本文主要介绍了最基本的java程序规则,和常用数据类型,其中侧重说了数组的一些操作. 面向java编程 java是纯面向对象语言,所有的程序都要 ...

  10. JAVA提高五:注解Annotation

    今天我们学习JDK5.0中一个非常重要的特性,叫做注解.是现在非常流行的一种方式,可以说因为配置XML 比较麻烦或者比容易查找出错误,现在越来越多的框架开始支持注解方式,比如注明的Spring 框架, ...

随机推荐

  1. gokit 统计分析 M2M接入服务 OTA固件升级 硬件社交化

    统计分析 M2M接入服务  OTA固件升级 硬件社交化 统计分析 为智能硬件定制的统计分析服务.只需添加入一行代码的集成工作,多维度的设备使用和用户行为数据就能自动统计出来. 演示 特色一:设备上线情 ...

  2. react 中使用 JsBarcode 显示条形码

    import React from 'react';import JsBarcode from 'jsbarcode'; export class RefundSheet extends React. ...

  3. 68、Schema的相关类

    public class SObjectSchema { public void testSchema(){ //获取SObject的token //1.先获取所有token,然后通过key获取需要的 ...

  4. Java短路运算符和非短路运算符

    在Java中短路运算符指的是"&&"(与) 和"||"(或) ,非短路运算符指的是"&" 和"|" ...

  5. echarts数据包坐标拾取工具

    http://geojson.io/#map=4/37.20/103.45

  6. EmWin 如何显示汉字 不用在文件中使用编码

    1. Font Converter for emWin 生成C文件字库 1.1 新建文件 1.2 选择字体 1.3 为了减小C文件体积,这里只加入自己需要的汉字,先把所有字体取消选择. 1.4 新建一 ...

  7. 运维01 VMware与Centos系统安装

    VMware与Centos系统安装   今日任务 1.Linux发行版的选择 2.vmware创建一个虚拟机(centos) 3.安装配置centos7 4.xshell配置连接虚拟机(centos) ...

  8. log4j日志格式化

    Apache log4j 提供了各种布局对象,每一个对象都可以根据各种布局格式记录数据.另外,也可以创建一个布局对象格式化测井数据中的特定应用的方法. 所有的布局对象 - Appender对象收到 L ...

  9. iview 的table组件,自带过滤功能

    html : <Table :columns="people" :data="scores"></Table> data: people ...

  10. NFS挂载error:reason given by server: Permission denied

    首先你得看看你的NFS服务有没有启动 然后你看看你要mount的文件夹有没有在NFS主机共享 然后再看权限对没对