Rights management: Rights management is required for systems involving user participation. Rights management belongs to the category of system security. Rights management is to realize the control of user access to the system. Users can be controlled according to security rules or security policies, and users can only access their own users. Authorized resources.
Rights management includes two parts: user==authentication==and==authorization==, referred to as ==authentication and authorization==. For resources that need access control, users must first undergo identity authentication. After the authentication is passed, users can access the resources only after they have access rights to the resources.
Identity authentication: Verify whether the user's identity is legal. The most commonly used simple identity authentication method is that the system checks whether the user name and password entered by the user are consistent with the user's user name and password stored in the system to determine whether the user's identity is correct. . An example in life: if a system such as a fingerprint is used, the fingerprint should be shown; for a card-swiping system such as a hardware Key, a card should be swiped.
==Authorization, that is, access control==, controls who can access which resources. After the subject performs == identity authentication == needs to be assigned permissions to access the resources of the system, some resources cannot be accessed without permission
Shiro is an authentication and authorization framework. Shiro can easily develop good enough applications, which can be used not only in the JavaSE environment, but also in the JavaEE environment. Shiro can help us with: authentication, authorization, encryption, session management, integration with the Web, caching, etc.
1. shiro's certification work
1.1, the key objects of authentication in shiro
Subject: Subject The user who accesses the system, the subject can be a user, a program, etc., and the authentication is called the subject;
Principal: Identity information - Account is the identity of the subject for authentication. Identity must be unique, such as user name, mobile phone number, mailbox address, etc. A principal can have multiple identities, but must have a principal Identity.
credential: credential information---password is security information that only the subject knows, such as passwords, certificates, etc.
1.2. Certification process
1.3 Authentication in Java (without database connection)
1.3.1 Create a maven project and add dependencies
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.9.0</version>
</dependency>
1.3.2 Create ini file
This option is in txt format
1.3.3 Test code
public static void main(String[] args) { //1. Get the SecutiryManager object DefaultSecurityManager securityManager = new DefaultSecurityManager(); //2. Read the ini file IniRealm iniRealm = new IniRealm("classpath:shiro.ini"); //3. Set the realm of securityManager securityManager.setRealm(iniRealm); //4. Set the securityManager context to take effect SecurityUtils.setSecurityManager(securityManager); //5. Get the subject object Subject subject= SecurityUtils.getSubject(); try { //The role of UsernamePasswordToken is to encapsulate the account number and password you entered. It is the account number and password entered by the customer. UsernamePasswordToken token=new UsernamePasswordToken("zhangsan","123456"); //Throwing an exception, realm compares your own comparison in shiro subject.login(token); System.out.println("login successful"); }catch (Exception e){ e.printStackTrace(); System.out.println("Incorrect username or password"); } }
1.3.4 Authentication Principle
Subject: Subject The login information is submitted to the SecurityManager, --->Authenticator---->According to the data provided by your realm to perform related authentication. realm---a class that interacts with the data source.
2. Authorization
2.1 Authorization Flowchart
2.2 Modification of the code
public static void main(String[] args) { //1. Get the SecutiryManager object DefaultSecurityManager securityManager = new DefaultSecurityManager(); // //2. Read the ini file IniRealm iniRealm = new IniRealm("classpath:shiro.ini"); //3. Set the realm of securityManager securityManager.setRealm(iniRealm); //4. Set the securityManager context to take effect SecurityUtils.setSecurityManager(securityManager); //5. Get the subject object Subject subject= SecurityUtils.getSubject(); try { //The role of UsernamePasswordToken is to encapsulate the account number and password you entered. It is the account number and password entered by the customer. UsernamePasswordToken token=new UsernamePasswordToken("zhangsan","123456"); //Throwing an exception, realm compares your own comparison in shiro subject.login(token); System.out.println("login successful"); }catch (Exception e){ e.printStackTrace(); System.out.println("Incorrect username or password"); } // subject.logout(); System.out.println("====================================================after login====================================="); boolean authenticated = subject.isAuthenticated(); if(authenticated){ //Determine whether the current login has the user:query permission boolean permitted = subject.isPermitted("user:update"); System.out.println(permitted); //From a role perspective boolean b = subject.hasRole("role1"); System.out.println(b); }else{ System.out.println("Please authenticate first"); } }
3. The underlying code of authentication
We analyze the source code and send our final authentication to realm to complete the authentication function and return an info. If the info is not null, the password is compared. If we use the account and password in the database to complete the authentication function, we need to customize a class and inherit AuthenticatingRealm.
4. Customize Realm Authentication
private UserService userService=new UserService(); //This method is used to complete the authentication function protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //1. Obtain an account according to the token String username = (String) authenticationToken.getPrincipal(); //2. Query user information according to the account User user = userService.findByUsername(username); if(user!=null){ //password obtained from the database SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),this.getName()); return info; } return null; }
5. Encryption
shiro it provides a lot of medium ciphers. The other most used is HashedCredentialsMatcher. Its bottom layer still uses Md5 encryption. Learn about MD5 encryption
public static void main(String[] args) { //source: plaintext to be encrypted Md5Hash md5Hash = new Md5Hash("123456"); System.out.println(md5Hash);//e10adc3949ba59abbe56e057f20f883e ciphertext---default md5 encryption is irreversible. But there are some cracked software on the Internet //salt: salt Md5Hash md5Hash1=new Md5Hash("123456","abc?!"); System.out.println(md5Hash1); //Set n encryption Md5Hash md5Hash2 = new Md5Hash("123456","abc?!",1024); }
5.1 shiro uses a password encryptor
Modify realm code
6. Customize the authorization function of realm
private UserService userService = new UserService(); //When to execute this method: This method will be executed when you perform permission verification protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { User user = (User) principalCollection.getPrimaryPrincipal(); //Query which permissions the user has based on the account List<String> list= userService.findPermissionByUsername(user.getUsername()); if(list!=null&&list.size()>0){ SimpleAuthorizationInfo info=new SimpleAuthorizationInfo(); info.addStringPermissions(list); return info; } return null; } // protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //1. Obtain an account according to the token String username = (String) authenticationToken.getPrincipal(); //2. Query user information according to the account User user = userService.findByUsername(username); if(user!=null){ //password obtained from the database ByteSource credentialsSalt=ByteSource.Util.bytes(user.getSalt()); SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),credentialsSalt,this.getName()); return info; } return null; }
test code
DefaultSecurityManager securityManager=new DefaultSecurityManager(); MyRealm myRealm=new MyRealm(); HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher(); credentialsMatcher.setHashAlgorithmName("MD5"); credentialsMatcher.setHashIterations(1024); myRealm.setCredentialsMatcher(credentialsMatcher); securityManager.setRealm(myRealm); SecurityUtils.setSecurityManager(securityManager); Subject subject = SecurityUtils.getSubject(); try { UsernamePasswordToken token = new UsernamePasswordToken("ykq", "123456"); subject.login(token); System.out.println(subject.isPermitted("user:query")); System.out.println(subject.isPermitted("user:update")); }catch (Exception e){ System.out.println("Account password error"); } }
7. ssm integration shiro
7.1. Integration steps
(1) Introduce dependencies
<!--shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.9.0</version>
</dependency>
(2) Modify the spring configuration file
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!--packet scan--> <context:component-scan base-package="com.wk"/> <!--Turn on annotations--> <mvc:annotation-driven/> <!--Release of static resources--> <mvc:default-servlet-handler/> <!-- start up Shrio annotations shiro Add in to controller should belong to springmvc Configuration --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor" /> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager" /> </bean> <!--spring Configuration--> <!--Data source configuration--> <bean id="ds" class="com.alibaba.druid.pool.DruidDataSource"> <!--driver name--> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/shiro?serverTimezone=Asia/Shanghai"/> <property name="username" value="root"/> <property name="password" value="123456de"/> <!--Initialize the number of connection pools--> <property name="initialSize" value="5"/> <!--at least the number--> <property name="minIdle" value="5"/> <!--maximum number--> <property name="maxActive" value="10"/> <!--Maximum wait time in milliseconds--> <property name="maxWait" value="3000"/> </bean> <!--sqlSessionFactory Integrate mybatis--> <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="ds"/> <!--set up mybatis path to map file--> <!-- <property name="mapperLocations" value="classpath:mapper/*.xml"/>--> <!----> </bean> <!--for dao Interface generation proxy implementation class--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!--for com.ykq.dao The interface under the package generates the proxy implementation class--> <property name="basePackage" value="com.wk.dao"/> </bean> <!--transaction management--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="ds"/> </bean> <!--Enable transaction management--> <tx:annotation-driven transaction-manager="transactionManager"/> <!--Integrate shiro config content--> <!--①SecurityManager--> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="realm"/> </bean> <!--Create custom realm class object--> <bean id="realm" class="com.wk.realm.MyRealm"> <property name="credentialsMatcher" ref="credentialsMatcher"/> </bean> <!--Create a password matcher--> <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="MD5"/> <property name="hashIterations" value="1024"/> </bean> <!--shiro filter factory: set filtering rules--> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> <!--If not logged in, the path to jump to--> <property name="loginUrl" value="/login.jsp"/> <!--No permission, jump path --> <property name="unauthorizedUrl" value="/unauthorized.jsp"/> <property name="filterChainDefinitions"> <value> /login=anon /**=authc </value> </property> <property name="filters"> <map> <entry key="authc"> <bean class="com.wk.filter.LoginFilter"/> </entry> </map> </property> </bean> </beans>
Modify the web.xml file
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--shiro filter proxy--> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <!--when tomcat Created at startup DipatcherServlet Default when accessing controller path created--> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
Modify the controller layer
7.2 Authorize users
This method is not secure, and users can still access after knowing the path of other permissions.
So we need to intercept, if the user does not have a certain permission, he cannot access the permission.
7.2.1 Access interception
-
Interceptor---Get the request path and then judge whether the current user has the permission based on your path.
-
spring provides an annotation when integrating shiro: you can load the corresponding method.
1. Turn on shiro annotations
<!-- Start Shrio's annotations -->
<bean id="lifecycleBeanPostProcessor"
class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
<bean
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor" />
<bean
class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager" />
</bean>
2. Use shiro annotations
@RequiresPermissions(value = {"/user/query","/user/aaa"},logical= Logical.OR)
We learned about global exception handling:
Related code demo
Annotations opened in springmvc
@RestController @RequestMapping("/user") public class UserController { //The default spring framework does not recognize this annotation. This annotation needs to be turned on in the springmvc configuration file @GetMapping("/query") @RequiresPermissions(value = {"/user/query"},logical= Logical.OR) public String query(){ return "user:query"; } @GetMapping ("/update") @RequiresPermissions(value = {"/user/update"}) public String update(){ return "user:update"; } @GetMapping ("/delete") @RequiresPermissions(value = {"/user/delete"}) public String delete(){ return "user:delete"; } @GetMapping ("/insert") @RequiresPermissions(value = {"/user/insert"}) public String insert(){ return "user:insert"; } @GetMapping ("/export") @RequiresPermissions(value = {"/user/export"}) public String export(){ return "user:export"; } }
The prompt given when there is no permission
@ControllerAdvice public class MyException { @ExceptionHandler(value = UnauthorizedException.class) @ResponseBody public CommonResult auth(UnauthorizedException e){ e.printStackTrace(); return new CommonResult(4002,"Insufficient permissions",null); } }
7.2.2 Without login
8. ssm integrates shiro to complete front-end and back-end separation
The so-called front-end and back-end are completely separated: the back-end responds to json data instead of web pages.
1. Login success or failure should return json data
2. When not logged in, it also returns json data
3. Access to unauthorized resources also requires club json.
8.1 Login success or failure should return json data
Modify the login interface
8.2 json data is also returned when not logged in
(1) Create a filter to inherit an interface of login verification
public class LoginFilter extends FormAuthenticationFilter { @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { response.setContentType("application/json;charset=utf-8"); PrintWriter writer = response.getWriter(); CommonResult commonResult = new CommonResult(4001, "not logged in", null); ObjectMapper objectMapper=new ObjectMapper(); String json = objectMapper.writeValueAsString(commonResult); writer.print(json); //Response to client with json data writer.flush(); writer.close(); return false; } }
(2) Register filter
8.3 If you don't have permission, you should return json data
9, springboot integration shiro
9.1 Related configuration and dependencies
(1) Dependence
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.12.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.ykq</groupId> <artifactId>qy151-springboot-shiro</artifactId> <version>0.0.1-SNAPSHOT</version> <name>qy151-springboot-shiro</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.1</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-starter</artifactId> <version>1.7.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
(2) application configuration file
#data source spring.datasource.url=jdbc:mysql://localhost:3306/shiro?serverTimezone=Asia/Shanghai spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver #The port number server.port=8808 #sql log mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
(1) application configuration file
import org.apache.shiro.authc.credential.CredentialsMatcher; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.realm.Realm; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.filter.DelegatingFilterProxy; import javax.servlet.Filter; import java.util.HashMap; @Configuration public class ShiroConfig { @Bean public SecurityManager securityManager(){ DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager(); securityManager.setRealm(realm()); return securityManager; } @Bean public Realm realm(){ MyRealm myRealm=new MyRealm(); myRealm.setCredentialsMatcher(credentialsMatcher()); return myRealm; } @Bean public CredentialsMatcher credentialsMatcher(){ HashedCredentialsMatcher credentialsMatcher=new HashedCredentialsMatcher(); credentialsMatcher.setHashAlgorithmName("MD5"); credentialsMatcher.setHashIterations(1024); return credentialsMatcher; } @Bean(value = "shiroFilter") public ShiroFilterFactoryBean filterFactoryBean(){ ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); factoryBean.setSecurityManager(securityManager()); //Set blocking rules HashMap<String,String> map=new HashMap<>(); map.put("/login","anon"); map.put("/**","authc"); factoryBean.setFilterChainDefinitionMap(map); //Set custom authentication filters HashMap<String,Filter> filterMap=new HashMap<String, Filter>(); filterMap.put("authc",new LoginFilter()); factoryBean.setFilters(filterMap); return factoryBean; } @Bean //register filter public FilterRegistrationBean<Filter> filterRegistrationBean(){ FilterRegistrationBean<Filter> filterRegistrationBean=new FilterRegistrationBean<>(); filterRegistrationBean.setName("shiroFilter"); filterRegistrationBean.setFilter(new DelegatingFilterProxy()); filterRegistrationBean.addUrlPatterns("/*"); return filterRegistrationBean; } }
(3) Create service dao
service
@Service public class UserService { @Autowired(required = false) private UserMapper userMapper; public User findByUsername(String username) { QueryWrapper<User> wrapper=new QueryWrapper<>(); wrapper.eq("username",username); User user=userMapper.selectOne(wrapper); return user; } public List<String> findPermissionByUsername(Integer userid) { List<String> list = userMapper.selectByUserId(userid); return list; } }
dao
@Mapper public interface UserMapper extends BaseMapper<User>{ @Select(value = "select percode from user_role ur join role_permission rp on ur.roleid=rp.roleid join permission p on rp.perid=p.perid where ur.userid=#{userid}") List<String> selectByUserId(Integer userid); }
(4) Create realm
public class MyRealm extends AuthorizingRealm { @Autowired private UserService userService; //When to execute this method: This method will be executed when you perform permission verification @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { User user = (User) principalCollection.getPrimaryPrincipal(); //Query which permissions the user has based on the account List<String> list= userService.findPermissionByUsername(user.getUserid()); if(list!=null&&list.size()>0){ SimpleAuthorizationInfo info=new SimpleAuthorizationInfo(); info.addStringPermissions(list); return info; } return null; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //1. Obtain an account according to the token String username = (String) authenticationToken.getPrincipal(); //2. Query user information according to the account User user = userService.findByUsername(username); if(user!=null){ //password obtained from the database ByteSource credentialsSalt=ByteSource.Util.bytes(user.getSalt()); SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getUserpwd(),credentialsSalt,this.getName()); return info; } return null; } }
Turn on shiro annotations
//start shiro annotation @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager()); return authorizationAttributeSourceAdvisor; } @Bean public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator(); advisorAutoProxyCreator.setProxyTargetClass(true); return advisorAutoProxyCreator; }
shiroconfig configuration
package com.wk.config; import com.wk.filter.LoginFilter; import com.wk.realm.MyRealm; import org.apache.shiro.authc.credential.CredentialsMatcher; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.realm.Realm; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.filter.DelegatingFilterProxy; import javax.servlet.Filter; import java.util.HashMap; @Configuration public class ShiroConfig { @Bean public DefaultWebSecurityManager securityManager(){ DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager(); securityManager.setRealm(realm()); return securityManager; } @Bean public Realm realm(){ MyRealm myRealm=new MyRealm(); myRealm.setCredentialsMatcher(credentialsMatcher()); return myRealm; } @Bean public CredentialsMatcher credentialsMatcher(){ HashedCredentialsMatcher credentialsMatcher=new HashedCredentialsMatcher(); credentialsMatcher.setHashAlgorithmName("MD5"); credentialsMatcher.setHashIterations(1024); return credentialsMatcher; } @Bean(value = "shiroFilter") public ShiroFilterFactoryBean filterFactoryBean(){ ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); factoryBean.setSecurityManager(securityManager()); //Set blocking rules HashMap<String,String> map=new HashMap<>(); map.put("/login","anon"); map.put("/*.css","anon"); map.put("/doc.html","anon"); map.put("/v2/api-docs", "anon"); map.put("/configuration/security", "anon");map.put("/swagger-resources", "anon"); map.put("/configuration/ui", "anon"); map.put("/**","authc"); factoryBean.setFilterChainDefinitionMap(map); //Set custom authentication filters HashMap<String,Filter> filterMap=new HashMap<String, Filter>(); filterMap.put("authc",new LoginFilter()); factoryBean.setFilters(filterMap); return factoryBean; } @Bean //register filter public FilterRegistrationBean<Filter> filterRegistrationBean(){ FilterRegistrationBean<Filter> filterRegistrationBean=new FilterRegistrationBean<>(); filterRegistrationBean.setName("shiroFilter"); filterRegistrationBean.setFilter(new DelegatingFilterProxy()); filterRegistrationBean.addUrlPatterns("/*"); return filterRegistrationBean; } //start shiro annotation @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager()); return authorizationAttributeSourceAdvisor; } @Bean public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator(); advisorAutoProxyCreator.setProxyTargetClass(true); return advisorAutoProxyCreator; } }