2 Commits

Author SHA1 Message Date
6760ee8db5 整合Shiro 2023-07-11 00:26:16 +08:00
60b061b7c6 整合Shiro 2023-07-09 23:28:42 +08:00
11 changed files with 242 additions and 0 deletions

36
pom.xml
View File

@@ -15,6 +15,7 @@
<description>netstate-proc</description> <description>netstate-proc</description>
<properties> <properties>
<java.version>17</java.version> <java.version>17</java.version>
<org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
</properties> </properties>
<dependencies> <dependencies>
<dependency> <dependency>
@@ -41,6 +42,25 @@
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.11.0</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
@@ -57,6 +77,22 @@
</excludes> </excludes>
</configuration> </configuration>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>

View File

@@ -0,0 +1,47 @@
package com.wuyiqi.netstateproc.config.shiro;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.JWTVerifier;
import com.auth0.jwt.interfaces.Payload;
import com.wuyiqi.netstateproc.convert.JwtConvert;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.mapstruct.factory.Mappers;
import java.time.Instant;
import java.util.List;
@Data
public class JwtToken implements AuthenticationToken {
private String token;
private String secret;
private static final JwtConvert jwtConvert = Mappers.getMapper(JwtConvert.class);
@Override
public String getPrincipal() {
return JWT.decode(token).getSubject();
}
@Override
public Payload getCredentials() throws JWTVerificationException {
Algorithm algorithm = Algorithm.HMAC256(Sha256Hash.toString(secret.getBytes()));
JWTVerifier verifier = JWT.require(algorithm).build();
return verifier.verify(token);
}
public static String generate(String subject, Long expire, List<Integer> rules, String secret) {
Algorithm algorithm = Algorithm.HMAC256(Sha256Hash.toString(secret.getBytes()));
Claims claims = new Claims(subject, Instant.now().plusSeconds(expire), Instant.now(), rules);
return JWT.create().withPayload(jwtConvert.conv2Map(claims)).sign(algorithm);
}
public record Claims(String subject, Instant expiresAt, Instant issuedAt, List<Integer> roles) {}
}

View File

@@ -0,0 +1,22 @@
package com.wuyiqi.netstateproc.config.shiro;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.subject.PrincipalCollection;
public class NetStateRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
return null;
}
}

View File

@@ -0,0 +1,22 @@
package com.wuyiqi.netstateproc.config.shiro;
import org.apache.catalina.Realm;
import org.apache.shiro.spring.config.ShiroAnnotationProcessorConfiguration;
import org.apache.shiro.spring.config.ShiroBeanConfiguration;
import org.apache.shiro.spring.config.ShiroConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import({ShiroBeanConfiguration.class,
ShiroConfiguration.class,
ShiroAnnotationProcessorConfiguration.class})
public class ShiroConfig {
@Bean
public Realm realm() {
return null;
}
}

View File

@@ -0,0 +1,28 @@
package com.wuyiqi.netstateproc.controller;
import com.wuyiqi.netstateproc.model.eneity.User;
import com.wuyiqi.netstateproc.model.rest.req.LoginReq;
import com.wuyiqi.netstateproc.model.rest.resp.Resp;
import com.wuyiqi.netstateproc.service.UserService;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@AllArgsConstructor
public class UserController {
private final UserService userService;
@PostMapping("/login")
public Resp<String> login(@RequestBody LoginReq req) {
return null;
}
@GetMapping("/test")
public Resp<User> test() {
return Resp.success(userService.findByUsername("admin"));
}
}

View File

@@ -0,0 +1,11 @@
package com.wuyiqi.netstateproc.convert;
import com.wuyiqi.netstateproc.config.shiro.JwtToken;
import org.mapstruct.Mapper;
import java.util.Map;
@Mapper
public interface JwtConvert {
Map<String, Object> conv2Map(JwtToken.Claims claims);
}

View File

@@ -0,0 +1,18 @@
package com.wuyiqi.netstateproc.model.eneity;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Data;
@Data
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String password;
private String username;
}

View File

@@ -0,0 +1,9 @@
package com.wuyiqi.netstateproc.model.rest.req;
import lombok.Data;
@Data
public class LoginReq {
private String username;
private String password;
}

View File

@@ -0,0 +1,20 @@
package com.wuyiqi.netstateproc.model.rest.resp;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
@Data
@Accessors(chain = true)
@AllArgsConstructor
public class Resp<T> {
private Integer code;
private String message;
private T data;
public static <T> Resp<T> success(T data) {
return new Resp<>(HttpStatus.OK.value(), "success", data);
}
}

View File

@@ -0,0 +1,10 @@
package com.wuyiqi.netstateproc.respository;
import com.wuyiqi.netstateproc.model.eneity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
//@Repository
public interface UserRepo extends JpaRepository<User, Long> {
User findByUsername(String username);
}

View File

@@ -0,0 +1,19 @@
package com.wuyiqi.netstateproc.service;
import com.wuyiqi.netstateproc.model.eneity.User;
import com.wuyiqi.netstateproc.respository.UserRepo;
import lombok.AllArgsConstructor;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Service;
@Service
@AllArgsConstructor
public class UserService {
private final UserRepo userRepo;
public User findByUsername(String username) {
return userRepo.findByUsername(username);
}
}