shiro#springboot
阅读原文时间:2023年07月13日阅读:2

1.

shiro的使用围绕着securityManager,权限需要从realm中来。

securityManager可以设置realm或者realms,或者通过设置authenticator来设置realm或realms。

realm中可以设置密码匹配器,credentialsMatcher,从而实现密码的加解密处理。

登录操作需要使用AuthenticationToken的子类的实例携带用户信息,传递给realm的认证方法,认证方法返回的是AuthenticationInfo实例,如果使用盐值,需要使用SimpleAuthenticationInfo来自动匹配及返回用户认证信息。

授权操作是使用PrincipalCollection的子类的实例,携带身份信息,传递给realm的鉴权方法,鉴权方法返回的是AuthorizationInfo的实例。

ByteSource salt = ByteSource.Util.bytes(user.getSalt());用于得到盐值密码。

2. 在spring boot中使用shiro时候必须要定义过滤器链,有如下两种方式配置:

方式1:

@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition chain = new DefaultShiroFilterChainDefinition();
//哪些请求可以匿名访问
chain.addPathDefinition("/user/login", "anon");
chain.addPathDefinition("/page/401", "anon");
chain.addPathDefinition("/page/403", "anon");
chain.addPathDefinition("/t5/hello", "anon");
chain.addPathDefinition("/t5/guest", "anon");

    //除了以上的请求外,其它请求都需要登录  
    chain.addPathDefinition("/\*\*", "authc");  
    return chain;  
}

方式2:

@Bean  
public ShiroFilterFactoryBean ShiroFilterFactoryBean(){  
    ShiroFilterFactoryBean sb = new ShiroFilterFactoryBean();  
    sb.setFilterChainDefinitionMap();  
    sb.setFilters(xx);  
    sb.setLoginUrl(xx);  
    sb.setSecurityManager(xx);  
    sb.setSuccessUrl(xx);  
    sb.setUnauthorizedUrl(xx);  
    return sb;  
}

其中第二种方法提供的bean对应的默认配置如下:

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.shiro.spring.config.web.autoconfigure;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.spring.web.config.AbstractShiroWebFilterConfiguration;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* @since 1.4.0
*/
@Configuration
@ConditionalOnProperty(name = "shiro.web.enabled", matchIfMissing = true)
public class ShiroWebFilterConfiguration extends AbstractShiroWebFilterConfiguration {

@Bean  
@ConditionalOnMissingBean  
@Override  
protected ShiroFilterFactoryBean shiroFilterFactoryBean() {  
    //通过方式二覆盖此处的配置  
    //通过方式二覆盖此处的配置  
    //通过方式二覆盖此处的配置  
    //通过方式二覆盖此处的配置  
    //通过方式二覆盖此处的配置  
    //通过方式二覆盖此处的配置  
    //通过方式二覆盖此处的配置  
    return super.shiroFilterFactoryBean();  
}

@Bean(name = "filterShiroFilterRegistrationBean")  
@ConditionalOnMissingBean  
protected FilterRegistrationBean filterShiroFilterRegistrationBean() throws Exception {

    FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();  
    filterRegistrationBean.setFilter((AbstractShiroFilter) shiroFilterFactoryBean().getObject());  
    filterRegistrationBean.setOrder(1);

    return filterRegistrationBean;  
}  

}

3. 自定义密码匹配器

/\*\*  
 \* 密码匹配器用于把传入的明文密码安装一定的算法加密成密文,有了密文才能和数据库中存储的密文密码进行比对  
 \* 密码匹配器在认证的时候自动被使用。  
 \*/  
@Bean(name = "hashedCredentialsMatcher")  
public HashedCredentialsMatcher hashedCredentialsMatcher() {  
    HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();  
    hashedCredentialsMatcher.setHashAlgorithmName("MD5");// 散列算法:这里使用MD5算法;  
    hashedCredentialsMatcher.setHashIterations(1024);// 散列的次数,比如散列两次,相当于 md5(md5(""));  
    return hashedCredentialsMatcher;  
}

4. 设置密码匹配器

方式1:在定义realm的时候设置密码匹配器

@Bean
public Realm realm() {
CustomRealm customRealm = new CustomRealm();
// 方式1:可以在自定义realm的时候设置密码匹配器
customRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return customRealm;
}

方式2:在realm类中,通过代码块的形式初始化密码匹配器

public class CustomRealm extends AuthorizingRealm {

@Autowired  
private UserService userService;  
@Autowired  
private RoleService roleService;  
@Autowired  
private PermService permService;

// 方式2: 通过代码类的代码块来初始化密码匹配器,不过这种方式有点丑  
{  
    //设置用于匹配密码的CredentialsMatcher  
    HashedCredentialsMatcher hashMatcher = new HashedCredentialsMatcher();  
    hashMatcher.setHashAlgorithmName(Sha256Hash.ALGORITHM\_NAME);  
    hashMatcher.setStoredCredentialsHexEncoded(false);  
    hashMatcher.setHashIterations(1024);  
    this.setCredentialsMatcher(hashMatcher);  
}

// other code

}

5. 如果密码中使用了盐值加密,盐值可以通过 ByteSource.Util.bytes(“盐是随机字符串或者username,一般是唯一的”); ,获得盐值后再real认证的时候返回的AuthenticationInfo就应该使用SimpleAuthenticationInfo最复杂的构造方法传入盐值。

6. shiro中默认的过滤器,需要查看org.apache.shiro.web.filter.mgt.DefaultFilter

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.shiro.web.filter.mgt;

import org.apache.shiro.util.ClassUtils;
import org.apache.shiro.web.filter.authc.*;
import org.apache.shiro.web.filter.authz.*;
import org.apache.shiro.web.filter.session.NoSessionCreationFilter;

import javax.servlet.Filter;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import java.util.LinkedHashMap;
import java.util.Map;

/**
* Enum representing all of the default Shiro Filter instances available to web applications. Each filter instance is
* typically accessible in configuration the {@link #name() name} of the enum constant.
*
* @since 1.0
*/
public enum DefaultFilter {

anon(AnonymousFilter.class),  
authc(FormAuthenticationFilter.class),  
authcBasic(BasicHttpAuthenticationFilter.class),  
logout(LogoutFilter.class),  
noSessionCreation(NoSessionCreationFilter.class),  
perms(PermissionsAuthorizationFilter.class),  
port(PortFilter.class),  
rest(HttpMethodPermissionFilter.class),  
roles(RolesAuthorizationFilter.class),  
ssl(SslFilter.class),  
user(UserFilter.class);

private final Class<? extends Filter> filterClass;

private DefaultFilter(Class<? extends Filter> filterClass) {  
    this.filterClass = filterClass;  
}

public Filter newInstance() {  
    return (Filter) ClassUtils.newInstance(this.filterClass);  
}

public Class<? extends Filter> getFilterClass() {  
    return this.filterClass;  
}

public static Map<String, Filter> createInstanceMap(FilterConfig config) {  
    Map<String, Filter> filters = new LinkedHashMap<String, Filter>(values().length);  
    for (DefaultFilter defaultFilter : values()) {  
        Filter filter = defaultFilter.newInstance();  
        if (config != null) {  
            try {  
                filter.init(config);  
            } catch (ServletException e) {  
                String msg = "Unable to correctly init default filter instance of type " +  
                        filter.getClass().getName();  
                throw new IllegalStateException(msg, e);  
            }  
        }  
        filters.put(defaultFilter.name(), filter);  
    }  
    return filters;  
}  

}

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章