shiro从入门到精通~配备实例讲解

Shiro安全矿建是目前最常用的作为登录注册的框架,提供了认证、授权、加密、和会话管理等功能;

Shiro的功能点:

    认证:验证用户身份;

    授权:对用户执行访问控制:判断用户是否被授权做某事;

    会话管理:在任何环境下使用SessionAPI,即使没有Web或EJB容器;

    加密:以更简洁易用的方式使用加密功能,保护或隐藏数据防止被偷窥;

    Realms:聚集一个或多个用户安全数据的数据源;

    单点登录:(SSO)功能;

为没有关联到登录的用户启用Remember Me服务。

Shiro的四大核心部分:(重点)

    Authentication(身份验证):简称为“登录”,即证明用户的身份;

    Authorization(授权):访问控制的过程,即决定是否有权限去访问手保护的资源;

    Session Management(会话管理):管理用户特定的会话,即使在非Web或EJB应用程序。

    Cryptography(加密):通过使用加密算法保持数据安全;

Shiro的三个核心组件:

    Subject:正与系统进行交互的用户或者服务。所有的Subject实例必须被绑定到一个SecurityManager上。

    SecurityManager:Shiro架构的核心,用来协调内部各安全组件,管理内部组件实例,并通过它来提供安全管理的各种服务。当Shiro与一个Subject进行交互时。实质上是幕后的SecurityManager处理所有繁重的Subject安全操作。

    Realms:本质上是一个特定安全的DAO。当配置Shiro时,必须指定至少一个Realm用来进行身份验证及授权。Shiro提供了多重可用的Realms来获取安全相关的数据。如关系数据库JDBC或属性文件等。可以定义自己Realms实现来代表自定义的数据源。

一、shiro整合Spring(此处以maven项目为例)

首先在pom.xml中添加jar包依赖:

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>${shiro.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>${shiro.version}</version>
</dependency>

准备基本的配置文件在spring配置文件中做如下配置:

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager"/>
    <property name="loginUrl" value="/mvc/login.xhtml"/>
    <property name="successUrl" value="/mvc/index.xhtml"/>
    <property name="filterChainDefinitions">
        <value>
            /mvc/mallszccb/pd/**/**/**/0/**/** = authc
            /mvc/docs/** = authc, perms[document:read]
            /currentUser = authc
            /** = anon
        </value>
    </property>
</bean>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="realm" ref="myRealm"/>
</bean>
<bean id="lifecycleBeanPostProcessor" 
      class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<bean id="myRealm" class="com.ifunpay.portal.security.MemberUserRealm"/>

配置文件准备完毕之后开始写Realm类,该方法必须继承AuthorizingRealm:

public class MemberUserRealm extends AuthorizingRealm {


    public static final String SALT = Sha256Hash.ALGORITHM_NAME;

    @Resource
    MemberUserService memberUserService;

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        String username = usernamePasswordToken.getUsername();
        MemberUserEntity memberUserEntity = memberUserService.getEntityByName(username);
        if(memberUserEntity != null){
            return new SimpleAuthenticationInfo(username, memberUserEntity.getPassword(), getSaltByteSource(), getName());
        }else{
            return null;
        }
    }


    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }


    public static String encryptPassword(Object password) {
        return new SimpleHash(SALT, password, getSaltByteSource())
                .toBase64();
    }

    private static ByteSource getSaltByteSource() {
        return ByteSource.Util.bytes(SALT);
    }


}

而后我在这里写了一个service来做登录业务:

@Component
public class ShiroSecurityService {

    public void auth(String username, String password){
        UsernamePasswordToken token = new UsernamePasswordToken(username, MemberUserRealm.encryptPassword(password));
        SecurityUtils.getSubject().login(token);
    }
}

最后在controller层做一个login来做shiro验证就ok了:

@RequestMapping(value = "/login", method = RequestMethod.POST)
public String auth(@RequestParam String username,
                 @RequestParam String password) {
    try {
        SavedRequest savedRequest = (SavedRequest) SecurityUtils.getSubject().getSession().getAttribute("shiroSavedRequest");
        String uri = savedRequest.getRequestURI();
        shiroSecurityService.auth(username, password);
        logger.info("login success"+uri);
        return "redirect:"+uri;
    } catch (Exception e) {
        logger.error("", e);
        return "redirect:/mvc/errorLogin?msg="+e.getMessage();
    }
}

猜你喜欢

转载自blog.csdn.net/qq_19167629/article/details/80986237