Giter Site home page Giter Site logo

spring-boot-shiro's Introduction

spring-boot-shiro's People

Contributors

ica10888 avatar smith-cruise avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spring-boot-shiro's Issues

关于token超时的问题

老铁, 能不能集成jwt的 refreshToken呢 , 现在过期时间是五分钟时间短, 就算延长了1小时的话, 那如果过期了的话, 用户还是要重新登录, 能不能通过不重新登录的方式, 而重新获取一个token呢 ?

Authorization format

Authorization的格式,对于JWT标准写法应该是Bearer格式吧,而我发现代码中确要求传username。
test
其他问题:
这个jwt的依赖是否能设置token的超时时间?

能否增加注解@hasRole的支持

关于使用前后分离,后端类RESTful风格改造配置Shiro的一些问题和想法

关于项目本身:

1. 个人理解shiro的cache主要用在session方面,既然使用了JWT鉴权,似乎就没必要关心shiro的cache机制,至于验证鉴权以外其他方面的缓存需,完全可以直接使用 spring-boot-starter-cache, 结合其他cache实现来做.

2.jwt 串放在Header的Authorization字段上的时候一般开头是Bearer,隔一个空格后才是jwt串,这样区别于BasicDigest

请问如何在Controller中获取Token中的username

非常感谢您的无私开源!

已反复阅读您项目的Readme.md内容,非常感谢。

如果用户携带token放问我,我如何在Controller中获取Token中的username,还是需要用户在提交时额外提交一个参数告诉我他的username呢?

anon好像不起作用 ?

Map<String, String> filterRuleMap = new HashMap<>();
// 访问401和404页面不通过我们的Filter
filterRuleMap.put("/401", "anon");
filterRuleMap.put("/login", "anon");
// 所有请求通过我们自己的JWT Filter
filterRuleMap.put("/**", "jwt");

    factoryBean.setFilterChainDefinitionMap(filterRuleMap);
    return factoryBean;

只要请求头里有Authorization就会去执行认证。

数据库移植出了一点问题

大佬你好,我就是在移植你那个数据,改到MySQL数据库时,出了一个很奇怪的问题

img.这个是地方百度了也是没有找到什么解决办法。

那个Authentication failed for token submission他是出在什么地方啦,大佬有什么解决的办法啊。头大撞墙

关于在realm进行登入时抛出异常的问题

在JWTFilter中有如下方法

@Override
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
    HttpServletRequest httpServletRequest = (HttpServletRequest) request;
    String authorization = httpServletRequest.getHeader("Authorization");
    authorization = authorization.replace("Bearer ", "");

    JWTToken token = new JWTToken(authorization);
    // 提交给realm进行登入,如果错误他会抛出异常并被捕获
    getSubject(request, response).login(token);
     // 如果没有抛出异常则代表登入成功,返回true
    return true;
 }

此时Header中带有Authorization,那么将会去MyRealm中进行用户验证。

如果Authorization传过来的token是错误的,就会抛出异常。但是再MyRealm.java 中的doGetAuthenticationInfo中抛出的异常,无法被ExceptionController所捕获,就导致返回的数据结构不统一了。
请问有解决办法吗?

doGetAuthorizationInfo方法不验证权限

当你发起一个请求之后,进入到自定义的Filter里面判断是否登录,假如你的token是正确的就直接进入该方法了。不会进入到doGetAuthorizationInfo方法的权限验证里面。

难道是我打开的姿势不对?

token过期

你好,想问下,token过期后会自动登录然后把新的token返回吗?

验证失败

使用url拼接登陆,获取token之后,获取不到权限。导致授权失败,无法访问权限页面

关于filter的两个问题请教

我想问下我执行的login方法JWTFilter里面的isLoginAttempt方法返回为啥为false,它的字面意思不是尝试登陆吗,
还有个executeLogin方法一直不会执行。(由于isLoginAttempt是false)我对这不是很理解。大佬指点一下

登录成功后权限访问不了

git clone 代码,启动运行成功

  1. 先访问login进行登录操作
  2. 登录成功后,访问/article还是返回You are guest.
  3. 登录成功后,访问/require_auth返回401.
    请问下是不是还有什么需要配置的

在MyRealm无法使用@Autowired service

通过修改ShiroConfig解决了:

@configuration
public class ShiroConfig {

@Bean
public SecurityManager securityManager() {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    // 设置realm.
    securityManager.setRealm(myShiroRealm());
    /*
     * 关闭shiro自带的session,详情见文档
     * http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29
     */
    DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
    DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
    defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
    subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
    securityManager.setSubjectDAO(subjectDAO);
    return securityManager;
}

@Bean
public MyRealm myShiroRealm() {
    return new MyRealm();
}

@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
    ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();

    factoryBean.setSecurityManager(securityManager);

    // shiro对于验证不通过的请求,会自动跳转到登录页,这里针对APP,设置为返回一个固定的
    factoryBean.setLoginUrl("/600");

    // 添加自己的过滤器并且取名为token,在下方使用
    Map<String, Filter> filterMap = new HashMap<>();
    filterMap.put("token", new TokenFilter());
    factoryBean.setFilters(filterMap);

    /*
     * 自定义url规则
     * http://shiro.apache.org/web.html#urls-
     */
    Map<String, String> filterRuleMap = new LinkedHashMap<>();
    // 配置不会被拦截的路径 顺序判断
    filterRuleMap.put("/600", "anon");
    filterRuleMap.put("/member/login", "anon");
    // 所有请求通过我们自己的token Filter
    filterRuleMap.put("/**", "token");

    factoryBean.setFilterChainDefinitionMap(filterRuleMap);
    return factoryBean;
}

/**
 * 下面的代码是添加注解支持
 */
@Bean
@DependsOn("lifecycleBeanPostProcessor")
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
    return new DefaultAdvisorAutoProxyCreator();
}

@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
    return new LifecycleBeanPostProcessor();
}

@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
    AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
    advisor.setSecurityManager(securityManager);
    return advisor;
}

}

发现个问题

Shiro源码是执行isAccessAllowed和onAccessDenied方法,现在只重写了isAccessAllowed,而onAccessDenied源码是重复调用了executeLogin方法,造成了循环多次调用Shiro认证方法

关闭 Session 的简单方法

在自定义 FilteronPreHandle 方法中添加如下代码即可。

request.setAttribute(DefaultSubjectContext.SESSION_CREATION_ENABLED, Boolean.FALSE);

对于不需要认证的页面使用 NoSessionCreationFilter 而不是 anon

filterRuleMap.put("/401", "noSessionCreation");

具体可看官方文档 NoSessionCreationFilter 和源码

package org.apache.shiro.web.filter.session;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.apache.shiro.web.filter.PathMatchingFilter;

public class NoSessionCreationFilter extends PathMatchingFilter {
    public NoSessionCreationFilter() {
    }

    protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        request.setAttribute(DefaultSubjectContext.SESSION_CREATION_ENABLED, Boolean.FALSE);
        return true;
    }
}

关于filter拦截配置问题的请教

您好:
我想问一下,这个项目中没有使用到任何web.xml文件配置filter,也没有使用注入filter用到的FilterRegistrationBean 类,请教为什么可以做到 shiro能拦截到所有请求的,具体实现是在哪里呢,麻烦了~

在此工程中pom文件引入spring-boot-starter-parent后起冲突的问题

在pom文件中加入以下依赖

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.44</version>
</dependency>

返回全部变成404

{
    "timestamp": 1519257821400,
    "status": 404,
    "error": "Not Found",
    "message": "No message available",
    "path": "/require_role"
}

后来发现把

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
</parent>

去掉就会正常。

或者保留spring-boot-starter-parent,把spring-boot-starter-data-jpa去掉也会正常,但不知道为什么会这样???

DELETE方法跨域问题

你好,有一个问题,preHandle(ServletRequest request, ServletResponse response)方法按照你的方式写好之后,执行Spring MVC 的@DeleteMapping的方法会报错
Method DELETE is not allowed by Access-Control-Allow-Methods in preflight response.
但是如果我将这一句
httpResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, httpRequest.getMethod());
修改为下面的样子的话,就可以正常执行
httpResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, httpRequest.getMethod()+", DELETE");

但我不太清楚为什么

整合mybatis事务失效

Application

@SpringBootApplication
@MapperScan(basePackages = {"org.inlighting.dao"})
@EnableTransactionManagement
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application .class);
    }
}

Service

public interface IUserService {
     UserBean getUser(String username) ;
}

ServiceImpl

@Service
public class UserService implements IUserService{
    private final UserMapper mapper;

    @Autowired
    public UserService(UserMapper mapper) {
        this.mapper = mapper;
    }

    @Transactional(rollbackFor = Exception.class)
    public UserBean getUser(String username) {
        // 没有此用户直接返回null
        Map<String, String> detail = mapper.selectUserByName(username);
        if (detail == null )
            return null;

        UserBean user = new UserBean();
        user.setUsername(username);
        user.setPassword(detail.get("USER_PSWD"));
        user.setRole(detail.get("ROLE_NAME"));
        user.setPermission("*");
        return user;
    }
}

log

2018-05-17 10:51:12.517 DEBUG 9948 --- [nio-1024-exec-1] org.mybatis.spring.SqlSessionUtils       : Creating a new SqlSession
2018-05-17 10:51:12.520 DEBUG 9948 --- [nio-1024-exec-1] org.mybatis.spring.SqlSessionUtils       : SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@57f320e4] was not registered for synchronization because synchronization is not active
2018-05-17 10:51:12.856  INFO 9948 --- [nio-1024-exec-1] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} inited
2018-05-17 10:51:12.860 DEBUG 9948 --- [nio-1024-exec-1] o.i.dao.UserMapper.selectUserByName      : ==>  Preparing: select * from user where userName = ?
2018-05-17 10:51:12.882 DEBUG 9948 --- [nio-1024-exec-1] o.i.dao.UserMapper.selectUserByName      : ==> Parameters: ricky(String)
2018-05-17 10:51:12.905 DEBUG 9948 --- [nio-1024-exec-1] o.i.dao.UserMapper.selectUserByName      : <==      Total: 1
2018-05-17 10:51:12.906 DEBUG 9948 --- [nio-1024-exec-1] org.mybatis.spring.SqlSessionUtils       : Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@57f320e4]

删除 DefaultAdvisorAutoProxyCreator 配置就正常

2018-05-17 11:02:05.302 DEBUG 7380 --- [nio-1024-exec-1] org.mybatis.spring.SqlSessionUtils       : Creating a new SqlSession
2018-05-17 11:02:05.307 DEBUG 7380 --- [nio-1024-exec-1] org.mybatis.spring.SqlSessionUtils       : Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6c7ef00b]
2018-05-17 11:02:05.320 DEBUG 7380 --- [nio-1024-exec-1] o.i.dao.UserMapper.selectUserByName      : ==>  Preparing: SELECT * from user where userName = ?
2018-05-17 11:02:05.342 DEBUG 7380 --- [nio-1024-exec-1] o.i.dao.UserMapper.selectUserByName      : ==> Parameters: ricky(String)
2018-05-17 11:02:05.365 DEBUG 7380 --- [nio-1024-exec-1] o.i.dao.UserMapper.selectUserByName      : <==      Total: 1
2018-05-17 11:02:05.366 DEBUG 7380 --- [nio-1024-exec-1] org.mybatis.spring.SqlSessionUtils       : Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6c7ef00b]
2018-05-17 11:02:05.366 DEBUG 7380 --- [nio-1024-exec-1] org.mybatis.spring.SqlSessionUtils       : Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6c7ef00b]
2018-05-17 11:02:05.366 DEBUG 7380 --- [nio-1024-exec-1] org.mybatis.spring.SqlSessionUtils       : Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6c7ef00b]
2018-05-17 11:02:05.366 DEBUG 7380 --- [nio-1024-exec-1] org.mybatis.spring.SqlSessionUtils       : Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6c7ef00b]

有其他的好方法吗?

fix it ?

This subject is anonymous - it does not have any identifying principals and " +
"authorization operations require an identity to check against. A Subject instance will " +
"acquire these identifying principals automatically after a successful login is performed " +
"be executing org.apache.shiro.subject.Subject.login(AuthenticationToken) or when 'Remember Me' " +
"functionality is enabled by the SecurityManager. This exception can also occur when a " +
"previously logged-in Subject has logged out which " +
"makes it anonymous again. Because an identity is currently not known due to any of these " +
"conditions, authorization is denied.

前后端分离shiro返回用户权限

请问下shiro在认证并授权后返回的SimpleAuthorizationInfo在controller中只能通过SecurityUtils.getSubject().hasRole()去判断认证的用户是否有某个权限而不能拿到这些权限的具体内容对么?查了很多资料,好像都是这样简单地去判断 。
我现在想实现的是返回给前端当前用户的角色以及他能访问的菜单栏的数据(菜单名称,url等),前端vuejs遍历这些返回的数据并渲染出菜单,jwt的部分已经实现了。虽然后台也可以单独地去查数据库然后直接返回,但是这样好像就没用到shiro的realm,请问您知道这个怎么解决么或者这个思路是错了么?

权限控制的方法

在控制器的其中一个方法加了权限判断注解,按我的理解是这个方法没有权限,访问就会受限,但是实际上这个控制器的其它方法也受到了同样的限制。请问这里的逻辑是怎样的
代码如下

@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private UserService userService;

    @GetMapping
//    @RequiresPermissions("user:index")
    public ResponseContent index() {
        return ResponseUtil.success(userRepository.findAll());
    }

    @PostMapping
    @RequiresPermissions("user:store")
    public ResponseContent store(@RequestParam String username, @RequestParam String password) {
        User user = userService.createNewUser(username, password);

        return ResponseUtil.success(user);
    }

    @DeleteMapping("/{id}")
//    @RequiresPermissions("user:del")
    public ResponseContent delete(@PathVariable long id) {
        userRepository.delete(id);
        return ResponseUtil.success();
    }
}

访问get http://localhost:8080/users会得到:

{
    "timestamp": 1516766046036,
    "status": 404,
    "error": "Not Found",
    "message": "No message available",
    "path": "/users"
}

关于doGetAuthenticationInfo的异常问题

当拿token来请求的时候,存在token过期无效,token本身无效的情况,没想明白为什么要抛出User didn't existed! 和 Username or password error 的异常,两个异常是不是在登陆时抛出更好一些。

页面跳转问题

你好,请教下, 按这个结构,页面上超链接跳转,js中location.href跳转时怎么实现权限控制?header中怎么加Authorization字段?

没跑起来

能看出来作者确实用心在写文档,但我能力有限跑起来有问题
hashmap怎么模拟的?
{ "username": "smith", "password": "smith123", "role": "user", "permission": "view" }
返回:
{ "code": 500, "msg": "Required String parameter 'username' is not present", "data": null }

想请教个关于token安全问题

请教大佬一个问题,如果这里的secret换成一个服务器独有的密钥会不会好点?
因为调用者如果知道是这种签名方式,是不是能通过自己的密码来签名,然后通过设置很大的过期时间达到无限请求接口的目的?

关于Authorization授权的时候出了一个问题。

作者大大你好,我在跑你这个项目的时候。访问/require_auth 这个接口的时候出现了401现象。##### token是拿到了的。。具体的访问内容如下。
  var token;
    $(".bu").click(function() {
      $.post('http://localhost:8080/login', {
        username: 'smith',
        password: 'smith123'

      }, function(data, textStatus, xhr) {
        /*optional stuff to do after success */
        console.log(data);
        token = data.data;
      });
    });

    $(".require_auth").click(function() {
      $.get('http://localhost:8080/require_auth', {
        Authorization: token
      }, function(data, textStatus, xhr) {
        /*optional stuff to do after success */
        console.log(data);
      });
    });

然后在访问这个接口时/require_auth 出现401

  @GetMapping("/require_auth")
    @RequiresAuthentication
    public ResponseBean requireAuth() {

        return new ResponseBean(200, "You are authenticated", null);
    }

反馈

作者大大这是为嘛呀,绝望脸,我那个token那个加错了的意思么

org.inlighting.controller.WebController#login

这个方法感觉没在shiro的机制中,如果直接访问该方法映射的请求,那么整个系统就相当于进行了两次登录操作(一次是该login本身登录逻辑,一次是shiro拦截器引起的登录逻辑),感觉怪怪的,不知道你的想法是啥

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.