apache Shiro登录

时间:2017-04-24 02:13:35

标签: spring apache shiro

我是Apache shiro的新手,并尝试使用authcBasic来保护Web服务。

我需要创建一个web服务,我可以通过提供用户名和密码登录,可以使用apache shiro的功能。

非常感谢任何指导

1 个答案:

答案 0 :(得分:1)

我创建了一个带有Spring-Boot的最小示例应用程序(因为#34; spring"标签)和Shiro,你可以找到here on GitHub。示例应用程序基于Spring文档中的"hello world" RESTful web service with Spring application。我通过these changes (GitHub commit)添加了Shiro:

shiro-spring依赖项添加到pom.xml:

</dependencies>
    [...]
    <!-- Apache Shiro -->
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-spring</artifactId>
        <version>1.3.2</version>
    </dependency>
</dependencies>

将shiro.ini从Shiro docs复制到资源:

# =============================================================================
# Tutorial INI configuration
#
# Usernames/passwords are based on the classic Mel Brooks' film "Spaceballs" :)
# =============================================================================

# -----------------------------------------------------------------------------
# Users and their (optional) assigned roles
# username = password, role1, role2, ..., roleN
# -----------------------------------------------------------------------------
[users]
root = secret, admin
guest = guest, guest
presidentskroob = 12345, president
darkhelmet = ludicrousspeed, darklord, schwartz
lonestarr = vespa, goodguy, schwartz

# -----------------------------------------------------------------------------
# Roles with assigned permissions
# roleName = perm1, perm2, ..., permN
# -----------------------------------------------------------------------------
[roles]
admin = *
schwartz = lightsaber:*
goodguy = winnebago:drive:eagle5

在Application.java中配置ShiroFilterSecurityManagerIniRealm以及Shiro annotations(改编自here):

@SpringBootApplication
public class Application {
      [...]
      @Bean(name = "shiroFilter")
      public FilterRegistrationBean shiroFilter() throws Exception {
          FilterRegistrationBean registration = new FilterRegistrationBean();
          registration.setFilter((AbstractShiroFilter) getShiroFilterFactoryBean().getObject());
          registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
          return registration;
      }

      @Bean
      public ShiroFilterFactoryBean getShiroFilterFactoryBean() {
          ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
          shiroFilterFactoryBean.setSecurityManager(securityManager());

          Map<String, String> filterChainDefinitionMap = shiroFilterFactoryBean.getFilterChainDefinitionMap();
          filterChainDefinitionMap.put("/**", "authcBasic");

          return shiroFilterFactoryBean;
      }

      @Bean(name = "securityManager")
      public DefaultWebSecurityManager securityManager() {
          DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
          dwsm.setRealm(getShiroIniRealm());
          final DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
          // disable session cookie
          sessionManager.setSessionIdCookieEnabled(false);
          dwsm.setSessionManager(sessionManager);
          return dwsm;
      }

      @Bean(name = "shiroIniRealm")
      @DependsOn("lifecycleBeanPostProcessor")
      public IniRealm getShiroIniRealm() {
          return new IniRealm("classpath:shiro.ini");
      }

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

      @Bean
      public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
          DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
          daap.setProxyTargetClass(true);
          return daap;
      }

      @Bean
      public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor() {
          AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
          aasa.setSecurityManager(securityManager());
          return new AuthorizationAttributeSourceAdvisor();
      }
}

使用参数&#34; admin&#34;添加@RequiresRoles注释到GreetingController进行测试:

@RestController
public class GreetingController {

      private static final String template = "Hello, %s!";
      private final AtomicLong counter = new AtomicLong();

      @RequestMapping("/greeting")
      @RequiresRoles(value = {"admin"})
      public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) {
          return new Greeting(counter.incrementAndGet(),
                              String.format(template, name));
      }
}  

使用以下命令签出并运行应用程序:

git clone https://github.com/opncow/gs-rest-service.git
cd gs-rest-service/complete/
./mvnw spring-boot:run

验证Shiro是否正常工作(使用HttpRequester或类似的插件来创建以下请求):

用户&#34; root&#34; (有&#34; admin&#34;角色),密码&#34;秘密&#34; (Base64编码的用户名:密码作为授权标头的值)

GET http://localhost:8080/greeting
Authorization: Basic cm9vdDpzZWNyZXQ=

 -- response --
200 
Set-Cookie:  rememberMe=deleteMe; Path=/; Max-Age=0; Expires=Thu, 11-May-2017 00:29:44 GMT
Content-Type:  application/json;charset=UTF-8
Transfer-Encoding:  chunked
Date:  Fri, 12 May 2017 00:29:44 GMT

{"id":1,"content":"Hello, World!"}

用户&#34;嘉宾&#34;密码&#34;客人&#34; (没有&#34;管理员&#34;角色):

GET http://localhost:8080/greeting
Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=

 -- response --
500 
Set-Cookie:  rememberMe=deleteMe; Path=/; Max-Age=0; Expires=Thu, 11-May-2017 00:44:18 GMT rememberMe=deleteMe; Path=/; Max-Age=0; Expires=Thu, 11-May-2017 00:44:18 GMT
Content-Type:  application/json;charset=UTF-8
Transfer-Encoding:  chunked
Date:  Fri, 12 May 2017 00:44:18 GMT
Connection:  close

{"timestamp":1494549858572,"status":500,"error":"Internal Server Error","exception":"org.apache.shiro.authz.UnauthorizedException","message":"Subject does not have role [admin]","path":"/greeting"}

可以看出,在第二个请求中,用户来宾已经过身份验证,但由于缺少&#34; admin&#34;而未被授权使用问候语资源。角色(这意味着注释正在运行)。

这是我能想象到的最小的例子。它使用Shiro的.ini配置/领域用于用户,密码和角色。对于真实世界项目,您可能必须使用更复杂的领域实现,例如Shiro的JdbcRealm