jfinal使用shiro实现登录功能,及Realm的使用

Shiro权限认证实践
本文介绍了一个基于Shiro框架的登录授权功能实现过程,包括从客户端获取信息到服务器端的身份验证与权限验证流程。详细展示了如何利用ShiroRealm类进行用户身份验证及权限分配。

现在开始实现框架的登录授权功能。

1.从客户端获取用户名,密码,是否记住等信息,生成token,通过subject.login(token)进行登录验证,如下:

public void login()
{
    String username = getPara("username");
    String password = getPara("password");
    String rememberMe = getPara("rememberMe");
    UsernamePasswordToken token = new UsernamePasswordToken(username, password, StrKit.notBlank(rememberMe) ? true : false);
    Subject subject = SecurityUtils.getSubject();
    try
    {
        //登录,即身份验证
        subject.login(token);
        redirect("/");
        return;
    }
    catch (AuthenticationException e)
    {
        //身份验证失败
    }
}

2.这里再简单叙述下验证及授权流程,作为上几篇认证和授权的总结。

(1)启动jfinal,会首先加载web.xml,并实例化里面的类,这里会创建EnvironmentLoaderListener的实例。EnvironmentLoaderListener在容器启动时创建 WebEnvironment 对象,并由该对象来读取 Shiro 配置文件,创建WebSecurityManager 与 FilterChainResolver 对象,同时创建一些有用的内置过滤器实例,并且自动的在[main]部分使用。如.ini文件配置,要使用authc,先定义其使用的类,这个类必须实现AuthenticatingFilter。

(2)调用方法subject.login(token)进行登录,最终委托接口SecurityManage的实现类的login方法。

(3)调用login方法的过程是:Authenticator会把相应的token传入Realm,从Realm获取身份验证信息,权限信息,然后进行身份验证和权限验证。

(4)ShiroRealm具体实现如下:

public class ShiroRealm extends AuthorizingRealm
{

    // 用户服务类
    private final UserService userService = UserService.me();
    // 角色服务类
    private final RoleService roleService = RoleService.me();
    // 权限服务类
    private final PermissionService permissionService = PermissionService.me();

    /**
     * 获取登录用户拥有的角色和权限
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals)
    {
        String username = (String)principals.getPrimaryPrincipal();//当前登录用户名
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        User user = userService.findByUsername(username); //根据用户名查找用户信息
        List<Role> roles = roleService.findRolesByUserId(user.getId());//根据用户名查找角色
        if(roles != null && roles.size() > 0)
        {
            for(Role role : roles)
            {
                authorizationInfo.addRole(role.getName());//将当前用户名下的角色存入authorizationInfo
            }
        }
        List<Permission> permissions = permissionService.findUserPermsByUserId(user.getId());
        if(permissions != null && permissions.size() > 0)
        {
            for(Permission permission : permissions)
            {
                authorizationInfo.addStringPermission(permission.getPermissionName());//将当前用户名下的权限存入authorizationInfo
            }
        }
        return authorizationInfo;
    }

    /**
     * 验证用户是否合法 
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
    {
        String username = (String)token.getPrincipal();  //当前登录用户名
        User user = userService.findByUsername(username); //根据用户名查找用户信息
        if(StrKit.isBlank(username))
        {
            throw new AuthenticationException("用户名不可以为空");
        }
        if (user == null)
        {
            throw new AuthenticationException("用户名或者密码错误");
        }
        return new SimpleAuthenticationInfo(user, user.getPassword(), getName()); //存入查询用户信息
    }
}

转载于:https://my.oschina.net/u/2427561/blog/1524585

实现 Apache Shiro 中的无密码登录功能,通常需要绕过传统的基于用户名和密码的身份验证机制。这种需求在一些特定场景中非常常见,例如通过短信验证码、第三方授权令牌(如 OAuth2)或生物识别等方式进行身份验证。 以下是实现无密码登录的一般方法和步骤: ### 1. 自定义 `Realm` Shiro 的 `Realm` 是用于连接数据源并提供用户信息的核心组件。为了支持无密码登录,可以自定义一个 `Realm`,使其能够根据非密码的信息(如验证码、令牌等)来验证用户身份。 ```java public class CustomNoPasswordRealm extends AuthorizingRealm { @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { // 授权逻辑 return null; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { // 在这里实现无密码验证逻辑 String username = (String) token.getPrincipal(); // 根据业务逻辑验证用户是否存在,并返回认证信息 if ("validUser".equals(username)) { return new SimpleAuthenticationInfo(username, "", getName()); } else { throw new UnknownAccountException("用户不存在"); } } } ``` ### 2. 使用自定义 `AuthenticationToken` 创建一个自定义的 `AuthenticationToken` 类型,以表示无密码登录请求。这个类将包含用户的唯一标识符(如手机号码、邮箱地址等),而不是传统的用户名和密码组合。 ```java public class NoPasswordAuthenticationToken implements AuthenticationToken { private String principal; public NoPasswordAuthenticationToken(String principal) { this.principal = principal; } @Override public Object getPrincipal() { return principal; } @Override public Object getCredentials() { return ""; // 不使用密码 } } ``` ### 3. 配置 Shiro 在配置文件中注册自定义的 `Realm` 和 `SecurityManager`,确保它们正确地集成到 Shiro 的安全框架中。 ```java @Configuration public class ShiroConfig { @Bean public Realm customNoPasswordRealm() { return new CustomNoPasswordRealm(); } @Bean public SecurityManager securityManager(Realm customNoPasswordRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(customNoPasswordRealm); return securityManager; } } ``` ### 4. 实现登录接口 在服务层实现登录接口,利用自定义的 `AuthenticationToken` 来完成无密码登录过程。 ```java @Service public class UserServiceImpl implements UserService { private final SecurityManager securityManager; public UserServiceImpl(SecurityManager securityManager) { this.securityManager = securityManager; } @Override public void login(UserLoginDTO loginDTO) { Subject currentUser = new Subject.Builder(securityManager).buildSubject(); AuthenticationToken token = new NoPasswordAuthenticationToken(loginDTO.getUsername()); try { currentUser.login(token); // 执行登录操作 } catch (AuthenticationException e) { // 处理异常情况 } } } ``` 通过以上步骤,可以在 Apache Shiro实现无密码登录的功能。需要注意的是,具体实现细节可能会根据实际应用场景有所不同,比如如何生成和验证验证码、如何处理用户状态等[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值