设为首页 收藏本站
查看: 325|回复: 0

[经验分享] Apache Shiro 集成-spring

[复制链接]

尚未签到

发表于 2017-1-2 07:48:34 | 显示全部楼层 |阅读模式
  自己根据shiro 源码捣鼓了一个shiro-spring , 弄上来也给大家看看,其实只是对源码稍加修改,不知道怎么部署源码的同学可以看看,eclipse 项目。
  一、在web.xml中添加shiro过滤器

    <!-- Shiro Filter is defined in the spring application context: -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
  二、在applicationContext.xml 加入 shiro 配置,另外配置相关数据库连接

<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- Sample RDBMS data source that would exist in any application - not Shiro related. -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver">
</property>
<property name="url"
value="jdbc:oracle:thin:@localhost:1521:orcl">
</property>
<property name="username" value="wforum"></property>
<property name="password" value="wforum"></property>
</bean>
<!-- Populates the sample database with sample users and roles. -->
<bean id="bootstrapDataPopulator" class="org.apache.shiro.samples.spring.BootstrapDataPopulator">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- Simulated business-tier "Manager", not Shiro related, just an example -->
<bean id="sampleManager" class="org.apache.shiro.samples.spring.DefaultSampleManager"/>
<!-- =========================================================
Shiro Core Components - Not Spring Specific
========================================================= -->
<!-- Shiro's main business-tier object for web-enabled applications
(use DefaultSecurityManager instead when there is no web environment)-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="cacheManager" ref="cacheManager"/>
<!-- Single realm app.  If you have multiple realms, use the 'realms' property instead. -->
<property name="sessionMode" value="native"/>
<property name="realm" ref="jdbcRealm"/>
</bean>
<!-- Let's use some enterprise caching support for better performance.  You can replace this with any enterprise
caching framework implementation that you like (Terracotta+Ehcache, Coherence, GigaSpaces, etc -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<!-- Set a net.sf.ehcache.CacheManager instance here if you already have one.  If not, a new one
will be creaed with a default config:
<property name="cacheManager" ref="ehCacheManager"/> -->
<!-- If you don't have a pre-built net.sf.ehcache.CacheManager instance to inject, but you want
a specific Ehcache configuration to be used, specify that here.  If you don't, a default
will be used.:
<property name="cacheManagerConfigFile" value="classpath:some/path/to/ehcache.xml"/> -->
</bean>
<!-- Used by the SecurityManager to access security data (users, roles, etc).
Many other realm implementations can be used too (PropertiesRealm,
LdapRealm, etc. -->
<bean id="jdbcRealm" class="org.apache.shiro.samples.spring.realm.SaltAwareJdbcRealm">
<property name="name" value="jdbcRealm"/>
<property name="dataSource" ref="dataSource"/>
<property name="credentialsMatcher">
<!-- The 'bootstrapDataPopulator' Sha256 hashes the password
(using the username as the salt) then base64 encodes it: -->
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="SHA-256"/>
<!-- true means hex encoded, false means base64 encoded -->
<property name="storedCredentialsHexEncoded" value="false"/>
</bean>
</property>
</bean>
<!-- =========================================================
Shiro Spring-specific integration
========================================================= -->
<!-- Post processor that automatically invokes init() and destroy() methods
for Spring-configured Shiro objects so you don't have to
1) specify an init-method and destroy-method attributes for every bean
definition and
2) even know which Shiro objects require these methods to be
called. -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<!-- Enable Shiro Annotations for Spring-configured beans.  Only run after
the lifecycleBeanProcessor has run: -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor"/>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
<!-- Secure Spring remoting:  Ensure any Spring Remoting method invocations can be associated
with a Subject for security checks. -->
<bean id="secureRemoteInvocationExecutor" class="org.apache.shiro.spring.remoting.SecureRemoteInvocationExecutor">
<property name="securityManager" ref="securityManager"/>
</bean>
<!-- Define the Shiro Filter here (as a FactoryBean) instead of directly in web.xml -
web.xml uses the DelegatingFilterProxy to access this bean.  This allows us
to wire things with more control as well utilize nice Spring things such as
PropertiesPlaceholderConfigurer and abstract beans or anything else we might need: -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/s/login"/>
<property name="successUrl" value="/s/index"/>
<property name="unauthorizedUrl" value="/s/unauthorized"/>
<!-- The 'filters' property is not necessary since any declared javax.servlet.Filter bean
defined will be automatically acquired and available via its beanName in chain
definitions, but you can perform overrides or parent/child consolidated configuration
here if you like: -->
<!-- <property name="filters">
<util:map>
<entry key="aName" value-ref="someFilterPojo"/>
</util:map>
</property> -->
<property name="filterChainDefinitions">
<value>
/favicon.ico = anon
/logo.png = anon
/shiro.css = anon
/s/login = anon
# allow WebStart to pull the jars for the swing app:
/*.jar = anon
# everything else requires authentication:
/** = authc
</value>
</property>
</bean>
</beans>

  三、实现JdbcRealm 重写认证方法,另外好像有几种不同Realm ,没细研究,有研究的同学可以补充下。

public class SaltAwareJdbcRealm extends JdbcRealm {
private static final Logger log = LoggerFactory.getLogger(SaltAwareJdbcRealm.class);
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String username = upToken.getUsername();
// Null username is invalid
if (username == null) {
throw new AccountException("Null usernames are not allowed by this realm.");
}
Connection conn = null;
AuthenticationInfo info = null;
try {
conn = dataSource.getConnection();
String password = getPasswordForUser(conn, username);
if (password == null) {
throw new UnknownAccountException("No account found for user [" + username + "]");
}
SimpleAuthenticationInfo saInfo = new SimpleAuthenticationInfo(username, password, getName());
/**
* This (very bad) example uses the username as the salt in this sample app.  DON'T DO THIS IN A REAL APP!
*
* Salts should not be based on anything that a user could enter (attackers can exploit this).  Instead
* they should ideally be cryptographically-strong randomly generated numbers.
*/
saInfo.setCredentialsSalt(ByteSource.Util.bytes(username));
info = saInfo;
} catch (SQLException e) {
final String message = "There was a SQL error while authenticating user [" + username + "]";
if (log.isErrorEnabled()) {
log.error(message, e);
}
// Rethrow any SQL errors as an authentication exception
throw new AuthenticationException(message, e);
} finally {
JdbcUtils.closeConnection(conn);
}
return info;
}
private String getPasswordForUser(Connection conn, String username) throws SQLException {
PreparedStatement ps = null;
ResultSet rs = null;
String password = null;
try {
ps = conn.prepareStatement(authenticationQuery);
ps.setString(1, username);
// Execute query
rs = ps.executeQuery();
// Loop over results - although we are only expecting one result, since usernames should be unique
boolean foundResult = false;
while (rs.next()) {
// Check to ensure only one row is processed
if (foundResult) {
throw new AuthenticationException("More than one user row found for user [" + username + "]. Usernames must be unique.");
}
password = rs.getString(1);
foundResult = true;
}
} finally {
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeStatement(ps);
}
return password;
}
}

  四、剩下的就是登录调用啦。

public class LoginController extends SimpleFormController {
private static transient final Logger log = LoggerFactory.getLogger(LoginController.class);
protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object cmd, BindException errors) throws Exception {
LoginCommand command = (LoginCommand) cmd;
UsernamePasswordToken token = new UsernamePasswordToken(command.getUsername(), command.getPassword());
try {
SecurityUtils.getSubject().login(token);
} catch (AuthenticationException e) {
log.debug("Error authenticating.", e);
errors.reject("error.invalidLogin", "The username or password was not correct.");
}
if (errors.hasErrors()) {
return showForm(request, response, errors);
} else {
return new ModelAndView(getSuccessView());
}
}
}
  五、另外这个例子中还有一个通过Session来保存值的功能,通过key,value的方式来存的,登录之后大家可以看到。代码就不贴了,说白了就没什么意思了,大家自己看吧。
  六、关于初始化数据
  程序启动时有初始化数据代码,但是好像有点问题,而且没有判断是否存在,重启就报错了,在这里我就把SQL贴出来。
  

create table users ( username varchar(255) primary key, password varchar(255) not null);
create table roles ( role_name varchar(255) primary key);
create table user_roles ( username varchar(255) not null, role_name varchar(255) not null, constraint user_roles_uq unique ( username, role_name));
create table roles_permissions ( role_name varchar(255) not null, permission varchar(255) not null, primary key (role_name, permission));

插入数据方法在 org.apache.shiro.samples.spring.BootstrapDataPopulator.afterPropertiesSet()
已经被我屏了,取消屏蔽,再启动 TOMCAT 之后。然后再屏掉吧。不然重启要出错。
   
   
  关于包什么的,我截个图,大家自己导,难找的包我已经附上了。
DSC0000.jpg
 

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-322563-1-1.html 上篇帖子: Apache优化配置总结 下篇帖子: apache POI 读取 Excel
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表