首页 行业资讯 宠物日常 宠物养护 宠物健康 宠物故事

ssm框架访问控制应该怎么做

发布网友

我来回答

2个回答

懂视网

原文出处:http://blog.csdn.net/dba_huangzj/article/details/344121,专题目录:http://blog.csdn.net/dba_huangzj/article/details/37906349 未经作者同意,任何人不得以原创形式发布,也不得已用于商业用途,本人不负责任何法律责任。 前一篇:http://b

原文出处:http://blog.csdn.net/dba_huangzj/article/details/344121,专题目录:http://blog.csdn.net/dba_huangzj/article/details/37906349

未经作者同意,任何人不得以“原创”形式发布,也不得已用于商业用途,本人不负责任何法律责任。

前一篇:http://blog.csdn.net/dba_huangzj/article/details/385357

前言:

登录名用于授权并访问服务器资源,如果需要访问数据库,需要对数据库内部的用户进行映射。用户是数据库级别的安全主体,访问数据库资源是授予给用户,而不是登录名。

实现:

有两种方法可以实现创建数据库用户,第一种是在服务器级别的登录名的属性页,另外一种是在数据库的【安全性】→【用户】节点中实现,这里使用第二种方式演示:

1.在SSMS中,选择【数据库】节点,并展开对应的数据库,选择【安全性】,右键【用户】选择【新建用户】

image

2. 在【常规】页,可以选择下面的用户类型:

image

类型简要说明:

用户类型 描述
SQL user with login(带登录名的SQL用户) 映射到一个SQL登录的用户。
SQL user without login(不带登录名的SQL用户) 没有映射到任何服务器级别的登录的用户,可以使用EXECUTE AS USER命令模拟执行。

User mapped to a certificate/User mapped to an asymmetric key (映射到证书/非对称密钥的用户)

通过一个签名密钥创建的用户,允许映射自一个远程实体。
Windows user (Windows用户) 映射到Windows身份验证的登录名的用户。

3. 输入用户名,可以和登录名一样,或者使用其他允许的名字,但是不能使用一些关键字、保留字等。选择一个登录名(或者输入映射的证书、密钥)。然后选择默认架构,如果没有选择架构,SQL Server会使用dbo作为默认架构。除了图形化操作,还可以用下面的T-SQL实现:

USE marketing; 
CREATE USER [Fred] FOR LOGIN [Fred];

4. 如果想查询已创建的用户,可以用sys.database_principals目录视图实现:

SELECT dp.name as UserName, sp.name as LoginName, dp.default_language_name, dp.default_schema_name, dp.type_desc, dp.create_date 
FROM sys.database_principals dp 
JOIN sys.server_principals sp ON dp.sid = sp.sid 
WHERE dp.type IN ('S', 'U') 
AND dp.principal_id > 4; 

其中1~4的principal_id为系统预设的用户。

原理:

你可以创建不带有登录名的用户,这种情况多数用在测试过程,或者仅用于安全上下文模拟(在第三章介绍)。要创建一个用户,需要在数据库层面上有ALTER ANY USER权限,等于固定数据库角色db_accessadmin,可以用GRANT ALTER ON USER::[用户名] to [特定需要用于管理的登录名]来实现。比如:

GRANT ALTER ON USER::[Fred] TO [Mary];

代表Mary这个登录名有权管理Fred这个用户。但是不给Mary过多的权限。

禁用用户:

和登录名的禁用不同,对于用户,没有ALTER USER XXXX DISABLE命令,在SSMS中也能看到没有这类勾选项。另外,一些系统用户,如guest、INFORMATION_SCHEMA,默认是禁用的。

如果要禁用用户,必须回收其CONNECT权限:

USE marketing; 
REVOKE CONNECT TO [Fred];

更多:

如果一个Windows 帐号属于某个Windows组,并且这个组作为一个登录被添加到SQL Server中,不仅可以创建一个数据库用户映射到整个组,也可以创建用户映射到单独的Windows帐号。比如,如果DOMAINFred是DOMAINDevelopers组的成员,并且这个组已经定义为SQL Server登录名,但是DOMAINFred登录未被添加,可以单独创建用户并授予权限:

CREATE USER [DOMAINFred] FROM LOGIN [DOMAINFred];

谁是dbo?

dbo代表Database Owner,是一个映射数据库拥有者的特殊数据库用户,当创建数据库时,所使用的登录名会被授予成owner,可以用下面语句查询:

SELECT SUSER_SNAME(owner_sid), name FROM sys.databases; 
-- or : 
SELECT SUSER_SNAME(sid) 
FROM sys.database_principals 
WHERE principal_id = USER_ID('dbo');

此时,登录名会自动映射到dbo中,并且授予整个库的所有权限,可以用下面语句修改:

ALTER AUTHORIZATION ON DATABASE::marketing TO sa; 

把数据库marketing的owner更改给sa。这种做法在把数据库移动到别的服务器时,而拥有者的SID不存在,就很有用。

dbo用户不能被重命名或者删除,也不能从db_owner角色中移除,数据库拥有者和sysadmin服务器角色成员会被视为数据库的dbo用户,逻辑上,作为数据库拥有者会映射到dbo中,而sysadmin角色成员不需要映射,实际上,即使当sysadmin成员映射到一个数据库的用户是,它会被视为dbo。

什么是guest用户?

在每一个数据库中,你会看到一个用户名叫guest的用户,它是一个不能移除的数据库固定系统用户,目的是允许没有映射到一个用户的登录名能匿名访问数据库。但是默认是禁用的,以防不必要访问。从安全性角度来说,保持它的禁用是比较好的方法,如果想启用,可以授予CONNECT权限:

USE marketing; 
GRANT CONNECT TO guest;

可以使用下面代码检查guest用户是否启用:

SELECT CAST(IIF(dp.state IN ('G', 'W'), 1, 0) AS bit) AS [HasDBAccess] 
FROM sys.database_principals u 
LEFT JOIN sys.database_permissions dp 
 ON dp.grantee_principal_id = u.principal_id and dp.type = 'CO' 
WHERE u.name = 'GUEST';

返回1即启用,-返回0为禁用。还可以用下面语句查看guest的权限:

SELECT permission_name, state_desc, OBJECT_NAME(major_id) as securable 
FROM sys.database_permissions 
WHERE grantee_principal_id = USER_ID('guest');

使用系统函数标识用户和登录

可以使用很多系统函数获取用户和登录的信息。

SYSTEM_USER和SUSER_SNAME(),返回当前登录信息,并包含SID。其中SUSER_SNAME()返回一个来自登录名或当前登录的SID,如果没有带有参数,在安全上下文更改时(EXECUTE AS ),会返回模拟登录。

CURRENT_USER和SESSION_USER返回当前数据库的当前上下文的用户名,USER_ID()或DATABASE_PRINCIPAL_ID()返回数据库的principal_id,而SUSER_SID()返回SID。

可以使用下面语句列出所有可以访问的数据库名:

SELECT [Name] 
FROM sys.databases 
WHERE HAS_DBACCESS ([Name]) = 1 
 AND database_id > 4 
ORDER BY [Name];

如果需要查询某个用户是否属于Windows的组成员,可以使用IS_MEMBER()函数:

SELECT IS_MEMBER('DOMAINdevelopers');

下面是可以使用的函数既描述:

函数名 描述
SYSTEM_USER 返回当前服务器登录名
SUSER_SNAME() 返回当前服务器登录名
SUSER_ID() 返回当前服务器SID
CURRENT_USER 返回当前数据库用户
SESSION_USER 返回当前数据库用户
USER_ID() 返回当前数据库principal_id
DATABASE_PRINCIPAL_ID() 返回当前数据库principal_id
ORIGINAL_LOGIN() 返回在上下文切换钱的原始登录名
HAS_DBACCESS('database') 1代表当前登录可以访问数据库
IS_MEMBER('group') 1代表当前登录是Windows组成员

热心网友

这个就在在人员表了添加一个身份的字段 user_rank ,用这个来控制。用户登录到时候就会用登录信息,把这个 user_rank 字段带出来,在页面或者链接时候加上判断,哈这是简单的,看下官方的。

shiro安全框架是目前为止作为登录注册最常用的框架,因为它十分的强大简单,提供了认证、授权、加密和会话管理等功能 。

shiro能做什么?

认证:验证用户的身份

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

会话管理:在任何环境下使用 Session API,即使没有 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),INI 及属性文件等。可以定义自己 Realm 实现来代表自定义的数据源。

shiro整合SSM框架:

1.加入 jar 包:以下jar包自行百度下载

2.配置 web.xml 文件

在web.xml中加入以下代码—shiro过滤器。

<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> 

3.在 Spring 的配置文件中配置 Shiro

Springmvc配置文件中:<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>

Spring配置文件中导入shiro配置文件:

<!-- 包含shiro的配置文件 -->
<import resource="classpath:applicationContext-shiro.xml"/>

新建applicationContext-shiro.xml

<?xml version="1.0" encoding="UTF-8"?><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.xsd">

<!-- 配置缓存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<!-- 指定 ehcache 的配置文件,下面会给到 -->
<property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml"/>
</bean>

<!-- 配置进行授权和认证的 Realm,要新增一个java类来实现,下面会有,class=包名.类名,init-methood是初始化的方法 -->
<bean id="myRealm"
class="shiro.MyRealm"
init-method="setCredentialMatcher"></bean>

<!-- 配置 Shiro 的 SecurityManager Bean. -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="cacheManager" ref="cacheManager"/>
<property name="realm" ref="myRealm"/>
</bean>

<!-- 配置 Bean 后置处理器: 会自动的调用和 Spring 整合后各个组件的生命周期方法. -->
<bean id="lifecycleBeanPostProcessor"
class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

<!-- 配置 ShiroFilter bean: 该 bean 的 id 必须和 web.xml 文件中配置的 shiro filter 的 name 一致  -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 装配 securityManager -->
<property name="securityManager" ref="securityManager"/>
<!-- 配置登陆页面 -->
<property name="loginUrl" value="/index.jsp"/>
<!-- 登陆成功后的一面 -->
<property name="successUrl" value="/shiro-success.jsp"/>
<property name="unauthorizedUrl" value="/shiro-unauthorized.jsp"/>
<!-- 具体配置需要拦截哪些 URL, 以及访问对应的 URL 时使用 Shiro 的什么 Filter 进行拦截.  -->
<property name="filterChainDefinitions">
<value>
<!-- 配置登出: 使用 logout 过滤器 -->
/shiro-logout = logout
/shiro-* = anon
/user.jsp = roles[user]
/admin.jsp = roles[admin]
/** = authc            </value>
</property>
</bean></beans>

导入ehcache-shiro.xml配置文件:

<!--
~ 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.  --><!-- EhCache XML configuration file used for Shiro spring sample application --><ehcache>

<!-- Sets the path to the directory where cache .data files are created.

If the path is a Java System Property it is replaced by
its value in the running VM.

The following properties are translated:
user.home - User's home directory
user.dir - User's current working directory
java.io.tmpdir - Default temp file path -->
<diskStore path="java.io.tmpdir/shiro-spring-sample"/>


<!--Default Cache configuration. These will applied to caches programmatically created through
the CacheManager.

The following attributes are required:

maxElementsInMemory            - Sets the maximum number of objects that will be created in memory
eternal                        - Sets whether elements are eternal. If eternal,  timeouts are ignored and the
element is never expired.
overflowToDisk                 - Sets whether elements can overflow to disk when the in-memory cache
has reached the maxInMemory limit.

The following attributes are optional:
timeToIdleSeconds              - Sets the time to idle for an element before it expires.
i.e. The maximum amount of time between accesses before an element expires
Is only used if the element is not eternal.
Optional attribute. A value of 0 means that an Element can idle for infinity.
The default value is 0.
timeToLiveSeconds              - Sets the time to live for an element before it expires.
i.e. The maximum time between creation time and when an element expires.
Is only used if the element is not eternal.
Optional attribute. A value of 0 means that and Element can live for infinity.
The default value is 0.
diskPersistent                 - Whether the disk store persists between restarts of the Virtual Machine.
The default value is false.
diskExpiryThreadIntervalSeconds- The number of seconds between runs of the disk expiry thread. The default value
is 120 seconds.
memoryStoreEvictionPolicy      - Policy would be enforced upon reaching the maxElementsInMemory limit. Default
policy is Least Recently Used (specified as LRU). Other policies available -
First In First Out (specified as FIFO) and Less Frequently Used
(specified as LFU)    -->

<defaultCache            maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
/>

<!-- We want eternal="true" (with no timeToIdle or timeToLive settings) because Shiro manages session
expirations explicitly.  If we set it to false and then set corresponding timeToIdle and timeToLive properties,
ehcache would evict sessions without Shiro's knowledge, which would cause many problems
(e.g. "My Shiro session timeout is 30 minutes - why isn't a session available after 2 minutes?"
Answer - ehcache expired it e to the timeToIdle property set to 120 seconds.)

diskPersistent=true since we want an enterprise session management feature - ability to use sessions after
even after a JVM restart.  -->
<cache name="shiro-activeSessionCache"
maxElementsInMemory="10000"
eternal="true"
overflowToDisk="true"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="600"/>

<cache name="org.apache.shiro.realm.SimpleAccountRealm.authorization"
maxElementsInMemory="100"
eternal="false"
timeToLiveSeconds="600"
overflowToDisk="false"/></ehcache>

准备好了,接下来要写Realm方法了,新建shiro包,在包下新建MyRealm.java文件继承AuthorizingRealm

package shiro;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authc.credential.HashedCredentialsMatcher;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.crypto.hash.Md5Hash;import org.apache.shiro.crypto.hash.SimpleHash;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.util.ByteSource;import org.springframework.beans.factory.annotation.Autowired;import bean.user;import .user;public class MyRealm extends AuthorizingRealm {
@Autowired    private user user;
String pass;    /**
* 授权:
*
*/
@Override    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
Object principal = principalCollection.getPrimaryPrincipal();//获取登录的用户名
if("admin".equals(principal)){               //两个if根据判断赋予登录用户权限
info.addRole("admin");
}        if("user".equals(principal)){
info.addRole("list");
}

info.addRole("user");
return info;
}    /*
* 用户验证
*
*/
@Override    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//1. token 中获取登录的 username! 注意不需要获取password.
Object principal = token.getPrincipal();
//2. 利用 username 查询数据库得到用户的信息.
user user=user.findbyname((String) principal);        if(user!=null){
pass=user.getPass();
}
String credentials = pass;        //3.设置盐值 ,(加密的调料,让加密出来的东西更具安全性,一般是通过数据库查询出来的。 简单的说,就是把密码根据特定的东西而进行动态加密,如果别人不知道你的盐值,就解不出你的密码)
String source = "abcdefg";
ByteSource credentialsSalt = new Md5Hash(source);

//当前 Realm 的name
String realmName = getName();        //返回值实例化
SimpleAuthenticationInfo info =
new SimpleAuthenticationInfo(principal, credentials,
credentialsSalt, realmName);
return info;
}    //init-method 配置.
public void setCredentialMatcher(){
HashedCredentialsMatcher  credentialsMatcher = new HashedCredentialsMatcher();
credentialsMatcher.setHashAlgorithmName("MD5");//MD5算法加密
credentialsMatcher.setHashIterations(1024);//1024次循环加密
setCredentialsMatcher(credentialsMatcher);
}

//用来测试的算出密码password盐值加密后的结果,下面方法用于新增用户添加到数据库操作的,我这里就直接用main获得,直接数据库添加了,省时间
public static void main(String[] args) {
String saltSource = "abcdef";
String hashAlgorithmName = "MD5";
String credentials = "passwor";
Object salt = new Md5Hash(saltSource);        int hashIterations = 1024;
Object result = new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations);
System.out.println(result);
}

}

好了,接下来我们写一个简单的action来通过shiro登录验证。

//登录认证
   @RequestMapping("/shiro-login")    public String login(@RequestParam("username") String username,
           @RequestParam("password") String password){
       Subject subject = SecurityUtils.getSubject();
       UsernamePasswordToken token = new UsernamePasswordToken(username, password);        
       try {            //执行认证操作.             subject.login(token);
       }catch (AuthenticationException ae) {
           System.out.println("登陆失败: " + ae.getMessage());            return "/index";
       }        
       return "/shiro-success";
   }

//温馨提示:记得在注册中密码存入数据库前也记得加密哦,提供一个utils方法//进行shiro加密,返回加密后的结果public static String md5(String pass){
String saltSource = "blog";    
String hashAlgorithmName = "MD5";
Object salt = new Md5Hash(saltSource);int hashIterations = 1024;    
Object result = new SimpleHash(hashAlgorithmName, pass, salt, hashIterations);
String password = result.toString();return password;
}

好了,shiro登录验证到这里完了

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com