首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件开发 >

SSH框架组合Spring Security3新手入门

2012-07-01 
SSH框架结合Spring Security3新手入门想给自己的程序加点安全控制,网上查了一下,说Spring Security是时下

SSH框架结合Spring Security3新手入门
想给自己的程序加点安全控制,网上查了一下,说Spring Security是时下最流行,与spring结合的最好的安全框架,就决定去试一下。

使用的Spring Security版本是 3.0.5,它对Spring的版本是有要求的,Spring的版本必须在3.0以上,于是更新了下Spring环境,去官网下一个就行了,我用的是3.0.5版本号与Spring Security的版本正好相同。
Sping3本质上与Spring2没有什么区别,配置文件也不用动,主要就是Spring原来的核心包被拆成了小块,所有的功能现在都可以灵活的添加了。话虽如此,但其实也不是把所有的dist目录下的包全导进去就行了,网上查了一下,除了下面两个包:
org.springframework.web.struts-3.0.5.RELEASE.jar
org.springframework.web.portlet-3.0.5.RELEASE.jar
不要导入,另外还要添加一个日志相关包commons-logging和一个aopalliance的包就可以正常运作了。
======================================================================
接下来我们正式进入Spring Security3的配置
我的数据库结构不同于"参考手册"上的默认配置,都是用Hibernate进行映射构建的,以下是类的代码:
Ⅰ.Account类存储用户的信息

package cn.com.jusesgod.domain.security;import java.util.Collection;import java.util.HashSet;import java.util.Set;import javax.persistence.CascadeType;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.JoinTable;import javax.persistence.OneToMany;import javax.persistence.Transient;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.userdetails.UserDetails;@Entitypublic class Account implements UserDetails{/** *  */private static final long serialVersionUID = 5275764647347461532L;private String username; //用户名private String password; //密码private boolean enable; //是否可用private Set<Authorities> grantedAuthorities; //表示用户所拥有的权限private int total; //玩这个游戏的总局数private int win; //赢的局数private int lose; //输的局数private int flee; //逃走的局数public Account(){}public Account(String username,String password){this.username = username;this.password = password;this.total = 0;this.win = 0;this.lose = 0;this.flee = 0;}public Account(String username,String password,int total,int win,int lose,int flee, Collection<GrantedAuthority> authorities){this.username = username;this.password = password;this.total = total;this.win = win;this.lose = lose;this.flee = flee;this.enable = true;grantedAuthorities = new HashSet<Authorities>();for(GrantedAuthority t : authorities){grantedAuthorities.add(new Authorities(this.username,t.getAuthority()));}}public void strat(){total += 1;}public void setFlee(int flee) {this.flee = flee;}public void setLose(int lose) {this.lose = lose;}public void setTotal(int total) {this.total = total;}public void setWin(int win) {this.win = win;}public void win(){win += 1;}public void lose(){lose += 1;}public void flee(){flee += 1;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Idpublic String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public int getTotal() {return total;}public int getWin() {return win;}public int getLose() {return lose;}public int getFlee() {return flee;}@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)//FetchType.EAGER表示立刻加载@JoinTable(name="authorities",joinColumns=@JoinColumn(name="username"))public Set<Authorities> getGrantedAuthorities() {return grantedAuthorities;}@Transientpublic Set<GrantedAuthority> getAuthorities() {Set<GrantedAuthority> ga = new HashSet<GrantedAuthority>();for(Authorities temp : grantedAuthorities){ga.add(temp);}return ga;}public void setGrantedAuthorities(Set<Authorities> authorities) {this.grantedAuthorities = authorities;}public boolean isEnable() {return enable;}public void setEnable(boolean enable) {this.enable = enable;}@Transientpublic boolean isAccountNonExpired() {// TODO Auto-generated method stubreturn true;}@Transientpublic boolean isAccountNonLocked() {// TODO Auto-generated method stubreturn true;}@Transientpublic boolean isCredentialsNonExpired() {// TODO Auto-generated method stubreturn true;}@Transientpublic boolean isEnabled() {return enable;}}


Ⅱ.Authorities对应Account中的grantedAuthorities属性,使用联合主键,有两个class文件共同实现
package cn.com.jusesgod.domain.security;import javax.persistence.Entity;import javax.persistence.Id;import javax.persistence.IdClass;import org.springframework.security.core.GrantedAuthority;@Entity@IdClass(AuthoritiesPK.class)public class Authorities implements GrantedAuthority {private String username;private String authority;public Authorities(){}public Authorities(String username,String authority){this.username = username;this.authority = authority;}public void setAuthority(String authority) {this.authority = authority;}@Idpublic String getUsername() {return username;}public void setUsername(String username) {this.username = username;}@Idpublic String getAuthority() {return authority;}}

package cn.com.jusesgod.domain.security;import java.io.Serializable;import javax.persistence.Embeddable;@Embeddablepublic class AuthoritiesPK implements Serializable {private String username;private String authority;public AuthoritiesPK(){}public AuthoritiesPK(String username,String authority){this.username = username;this.authority = authority;}public void setAuthority(String authority) {this.authority = authority;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getAuthority() {return authority;}}


1.配置web.xml文件,照着参考文档我们添加如下几个标签
<filter>  <filter-name>springSecurityFilterChain</filter-name>  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class></filter><filter-mapping>  <filter-name>springSecurityFilterChain</filter-name>  <url-pattern>/*</url-pattern></filter-mapping>


2.用Spring配置Spring Security,我写了两个文件进行配置
第一个用了命名空间,主要配置Spring Security的主体
<?xml version="1.0" encoding="UTF-8"?><beans:beans xmlns="http://www.springframework.org/schema/security"  xmlns:beans="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           http://www.springframework.org/schema/security           http://www.springframework.org/schema/security/spring-security-3.0.xsd">               <http auto-config="true" access-denied-page="/error.html">    <intercept-url pattern="/login.*" filters="none"/>    <intercept-url pattern="/role_*" access="ROLE_USER"/>    <form-login login-page="/login.html" default-target-url="/role_hall.html" authentication-failure-url="/login.jsp"/>    <custom-filter ref="authenticationFilter" before="FORM_LOGIN_FILTER"/>    <!--     第二次登录阻止,用户会被转发到 form-login 标签里定义的  authentication-failure-url 的地址    如果是form-base登录,用户会被转发到 session-management 中 session-authention-error-url 的地址    session-fixation-protection 防止Session固定攻击(2.3.3.3)    -migrateSession 创建一个新的session,把原来session中所有属性复制到新session中。这是默认值    -none 什么也不做    -newSession 创建一个新的"干净的"session,不会复制session中的数据。     -->    <session-management session-fixation-protection="migrateSession" invalid-session-url="/error.html">    <!--    max-session    error-if-maxinum-exceeded     -->    <concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/>    </session-management>    </http>        <authentication-manager>    <authentication-provider  user-service-ref="accoutJDBCImpl">    </authentication-provider>    </authentication-manager>        <global-method-security secured-annotations="enabled" jsr250-annotations="enabled"></global-method-security>    </beans:beans>

另一个用来配置其中用到的注入类的声明
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"     xmlns:security="http://www.springframework.org/schema/security"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"          xmlns:aop="http://www.springframework.org/schema/aop"           xmlns:tx="http://www.springframework.org/schema/tx"           xmlns:context="http://www.springframework.org/schema/context"           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd              http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd              http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd              http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd           http://www.springframework.org/schema/security           http://www.springframework.org/schema/security/spring-security-3.0.xsd"><bean id="authenticationFilter" ref="authenticationManager"></property><property name="filterProcessesUrl" value="/j_spring_security_check"></property></bean><bean id="authenticationManager" ref="accoutJDBCImpl"></property></bean><bean id="accoutJDBCImpl" ref="dataSource"></property></bean><bean id="authenticationProcessingFilterEntryPoint"       value="/login"></property>   </bean>  </beans>


3.可以看出来,上面有些注入的类是我自己自定义的,为了让我的数据结构能够让Spring Security识别,我对如下几个默认组件进行了修改,然后添加到了框架中,下面附上代码

MyDaoAuthenticationProvider
package cn.com.jusesgod.authentication.provider;import org.springframework.dao.DataAccessException;import org.springframework.security.authentication.AuthenticationServiceException;import org.springframework.security.authentication.BadCredentialsException;import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;import org.springframework.security.authentication.dao.SaltSource;import org.springframework.security.authentication.encoding.PasswordEncoder;import org.springframework.security.authentication.encoding.PlaintextPasswordEncoder;import org.springframework.security.core.AuthenticationException;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.util.Assert;public class MyDaoAuthenticationProvider extendsAbstractUserDetailsAuthenticationProvider { private PasswordEncoder passwordEncoder = new PlaintextPasswordEncoder();    private SaltSource saltSource;    private UserDetailsService userDetailsService;    private boolean includeDetailsObject = true;    //~ Methods ========================================================================================================    protected void additionalAuthenticationChecks(UserDetails userDetails,            UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {        Object salt = null;        if (this.saltSource != null) {            salt = this.saltSource.getSalt(userDetails);        }        if (authentication.getCredentials() == null) {            logger.debug("Authentication failed: no credentials provided");            throw new BadCredentialsException(messages.getMessage(                    "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"),                    includeDetailsObject ? userDetails : null);        }        String presentedPassword = authentication.getCredentials().toString();        logger.debug("presentedPassword:" + presentedPassword);        logger.debug("userDetails.getPassword():" + userDetails.getPassword());        System.out.println(presentedPassword);                if (!passwordEncoder.isPasswordValid(userDetails.getPassword(), presentedPassword, salt)) {            logger.debug("Authentication failed: password does not match stored value");            throw new BadCredentialsException(messages.getMessage(                    "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"),                    includeDetailsObject ? userDetails : null);        }    }    protected void doAfterPropertiesSet() throws Exception {        Assert.notNull(this.userDetailsService, "A UserDetailsService must be set");    }    protected final UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)            throws AuthenticationException {        UserDetails loadedUser;        try {            loadedUser = this.getUserDetailsService().loadUserByUsername(username);        }        catch (DataAccessException repositoryProblem) {            throw new AuthenticationServiceException(repositoryProblem.getMessage(), repositoryProblem);        }        if (loadedUser == null) {            throw new AuthenticationServiceException(                    "UserDetailsService returned null, which is an interface contract violation");        }        return loadedUser;    }    /**     * Sets the PasswordEncoder instance to be used to encode and validate passwords.     * If not set, {@link PlaintextPasswordEncoder} will be used by default.     *     * @param passwordEncoder The passwordEncoder to use     */    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {        this.passwordEncoder = passwordEncoder;    }    protected PasswordEncoder getPasswordEncoder() {        return passwordEncoder;    }    /**     * The source of salts to use when decoding passwords. <code>null</code>     * is a valid value, meaning the <code>DaoAuthenticationProvider</code>     * will present <code>null</code> to the relevant <code>PasswordEncoder</code>.     *     * @param saltSource to use when attempting to decode passwords via the <code>PasswordEncoder</code>     */    public void setSaltSource(SaltSource saltSource) {        this.saltSource = saltSource;    }    protected SaltSource getSaltSource() {        return saltSource;    }    public void setUserDetailsService(UserDetailsService userDetailsService) {        this.userDetailsService = userDetailsService;    }    protected UserDetailsService getUserDetailsService() {        return userDetailsService;    }    protected boolean isIncludeDetailsObject() {        return includeDetailsObject;    }    /**     * Determines whether the UserDetails will be included in the <tt>extraInformation</tt> field of a     * thrown BadCredentialsException. Defaults to true, but can be set to false if the exception will be     * used with a remoting protocol, for example.     *     * @deprecated use {@link org.springframework.security.authentication.ProviderManager#setClearExtraInformation(boolean)}     */    public void setIncludeDetailsObject(boolean includeDetailsObject) {        this.includeDetailsObject = includeDetailsObject;    }}


AccountJDBCImpl
package cn.com.jusesgod.service.impl;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.HashSet;import java.util.List;import java.util.Set;import org.springframework.context.ApplicationContextException;import org.springframework.context.support.MessageSourceAccessor;import org.springframework.dao.DataAccessException;import org.springframework.jdbc.core.RowMapper;import org.springframework.jdbc.core.support.JdbcDaoSupport;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.SpringSecurityMessageSource;import org.springframework.security.core.authority.GrantedAuthorityImpl;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.core.userdetails.UsernameNotFoundException;import org.springframework.util.Assert;import cn.com.jusesgod.domain.security.Account;/** * <tt>UserDetailsServiceRetrieves</tt> implementation which retrieves the user details * (username, password, enabled flag, and authorities) from a database using JDBC queries. * UserDetailsServiceRettrieves * 实现了如何去得到用用户的信息(username,password,enabled flag,和authorite)通过JDBC查询获取数据源 * * <h3>Default Schema</h3> * 默认的模式 * A default database schema is assumed, with two tables "users" and "authorities". *一个默认的数据模式被设定,有两个表"user"和"authorities" * <h4>The Users table</h4> *User表 * This table contains the login name, password and enabled status of the user. * * <table> * <tr><th>Column</th></tr> * <tr><td>username</td></tr> * <tr><td>password</td></tr> * <tr><td>enabled</td></tr> * </table> * * <h4>The Authorities Table</h4> *Authorities表 * <table> * <tr><th>Column</th></tr> * <tr><td>username</td></tr> * <tr><td>authority</td></tr> * </table> * * If you are using an existing schema you will have to set the queries <tt>usersByUsernameQuery</tt> and * <tt>authoritiesByUsernameQuery</tt> to match your database setup * 如果你使用一个存在的模式,你必须设置查询方法"usersByUsernameQuery"和"authoritiesByUsernameQuery"去适应你的数据源设置 * (see {@link #DEF_USERS_BY_USERNAME_QUERY} and {@link #DEF_AUTHORITIES_BY_USERNAME_QUERY}). *查看这两个变量会有帮助 * * <p> * In order to minimise backward compatibility issues, this implementation doesn't recognise the expiration of user * accounts or the expiration of user credentials. However, it does recognise and honour the user enabled/disabled * column. This should map to a <tt>boolean</tt> type in the result set (the SQL type will depend on the * database you are using). All the other columns map to <tt>String</tt>s. * 为了尽量减少向后兼容性的问题,这个实现不关心用户账户的期限或者用户证书的期限。而只关心注意用户是否可用(enable/disable列),这需要设置成一个 * boolean的类型在返回的设置里(在数据库保存的SQL属性取决于你的数据库)所有其他的属性使用String类型 * * <h3>Group Support</h3> * 组权限支持 * Support for group-based authorities can be enabled by setting the <tt>enableGroups</tt> property to <tt>true</tt> * (you may also then wish to set <tt>enableAuthorities</tt> to <tt>false</tt> to disable loading of authorities * directly). With this approach, authorities are allocated to groups and a user's authorities are determined based * on the groups they are a member of. The net result is the same (a UserDetails containing a set of * <tt>GrantedAuthority</tt>s is loaded), but the different persistence strategy may be more suitable for the * administration of some applications. * <p> * 对于支持组权限,我们需要设置enableGroups属性为true(你应当还希望去设置enableAuthorities为false去阻止导入authorities表中的权限设置) * 通过这种方法,权限被分成一组一组的,并且用户的权限被通过组的方法确定他们归属于那一个权限组。网络要求同样的(一个UserDetails包含 * 一个GrantedAuthority的设置被读取),但是不同的应用可能需要不同的持久化策略。 *  * When groups are being used, the tables "groups", "group_members" and "group_authorities" are used. See * {@link #DEF_GROUP_AUTHORITIES_BY_USERNAME_QUERY} for the default query which is used to load the group authorities. * Again you can customize this by setting the <tt>groupAuthoritiesByUsernameQuery</tt> property, but the format of * the rows returned should match the default. * 当组权限被使用,表groups,group_members和group_authorities也被使用。参看DEF_GROUP_AUTHORITIES_BY_USERNAME_QUERY属性,了解 * 默认的组权限查询语句。 * 同样,你可以去自定义这个属性通过设置groupAuthoritiesByUsernameQuery属性,但是返回的结果列会被格式化成默认的形式。 * * @author Ben Alex * @author colin sampaleanu * @author Luke Taylor */public class AccountJDBCImpl extends JdbcDaoSupport implements UserDetailsService {//~ Static fields/initializers =====================================================================================    public static final String DEF_USERS_BY_USERNAME_QUERY =            "select username,password,enable " +            "from Account " +            "where username = ?";    public static final String DEF_AUTHORITIES_BY_USERNAME_QUERY =            "select username,authority " +            "from Authorities " +            "where username = ?";    public static final String DEF_GROUP_AUTHORITIES_BY_USERNAME_QUERY =            "select g.id, g.group_name, ga.authority " +            "from groups g, group_members gm, group_authorities ga " +            "where gm.username = ? " +            "and g.id = ga.group_id " +            "and g.id = gm.group_id";    //~ Instance fields ================================================================================================    protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();    private String authoritiesByUsernameQuery;    private String groupAuthoritiesByUsernameQuery;    private String usersByUsernameQuery;    private String rolePrefix = "";    private boolean usernameBasedPrimaryKey = true;    private boolean enableAuthorities = true;    private boolean enableGroups = false;    //~ Constructors ===================================================================================================    public AccountJDBCImpl() {        usersByUsernameQuery = DEF_USERS_BY_USERNAME_QUERY;        authoritiesByUsernameQuery = DEF_AUTHORITIES_BY_USERNAME_QUERY;        groupAuthoritiesByUsernameQuery = DEF_GROUP_AUTHORITIES_BY_USERNAME_QUERY;    }    //~ Methods ========================================================================================================    /**     * Allows subclasses to add their own granted authorities to the list to be returned in the <tt>UserDetails</tt>.     *  允许子类添加他们自己的授权权限到列表里,在UserDetails里面被返回。     *     * @param username the username, for use by finder methods     * @param authorities the current granted authorities, as populated from the <code>authoritiesByUsername</code>     *        mapping     */    protected void addCustomAuthorities(String username, List<GrantedAuthority> authorities) {        }    public String getUsersByUsernameQuery() {        return usersByUsernameQuery;    }    protected void initDao() throws ApplicationContextException {    //确保两个权限模式必有一个在使用        Assert.isTrue(enableAuthorities || enableGroups, "Use of either authorities or groups must be enabled");    }    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {        List<UserDetails> users = loadUsersByUsername(username);                if (users.size() == 0) {            logger.debug("Query returned no results for user '" + username + "'");            throw new UsernameNotFoundException(                    messages.getMessage("JdbcDaoImpl.notFound", new Object[]{username}, "Username {0} not found"), username);        }        UserDetails user = users.get(0); // contains no GrantedAuthority[]        Set<GrantedAuthority> dbAuthsSet = new HashSet<GrantedAuthority>();        if (enableAuthorities) {            dbAuthsSet.addAll(loadUserAuthorities(user.getUsername()));        }        if (enableGroups) {            dbAuthsSet.addAll(loadGroupAuthorities(user.getUsername()));        }        List<GrantedAuthority> dbAuths = new ArrayList<GrantedAuthority>(dbAuthsSet);        addCustomAuthorities(user.getUsername(), dbAuths);        if (dbAuths.size() == 0) {            logger.debug("User '" + username + "' has no authorities and will be treated as 'not found'");            throw new UsernameNotFoundException(                    messages.getMessage("JdbcDaoImpl.noAuthority",                            new Object[] {username}, "User {0} has no GrantedAuthority"), username);        }        System.out.println("dbAuths:" + dbAuths.get(0).getAuthority());        return createUserDetails(username, user, dbAuths);    }    /**     * Executes the SQL <tt>usersByUsernameQuery</tt> and returns a list of UserDetails objects.     * There should normally only be one matching user.     */    protected List<UserDetails> loadUsersByUsername(String username) {        return getJdbcTemplate().query(usersByUsernameQuery, new String[] {username}, new RowMapper<UserDetails>() {            public UserDetails mapRow(ResultSet rs, int rowNum) throws SQLException {                String username = rs.getString(1);                String password = rs.getString(2);                return new Account(username,password,0,0,0,0,new HashSet<GrantedAuthority>());            }        });    }    /**     * Loads authorities by executing the SQL from <tt>authoritiesByUsernameQuery</tt>.     *     * @return a list of GrantedAuthority objects for the user     */    protected List<GrantedAuthority> loadUserAuthorities(String username) {        return getJdbcTemplate().query(authoritiesByUsernameQuery, new String[] {username}, new RowMapper<GrantedAuthority>() {            public GrantedAuthority mapRow(ResultSet rs, int rowNum) throws SQLException {                String roleName = rolePrefix + rs.getString(2);                logger.debug("row authorities:" + roleName + " to " + rs.getString(1));                GrantedAuthorityImpl authority = new GrantedAuthorityImpl(roleName);                return authority;            }        });    }    /**     * Loads authorities by executing the SQL from <tt>groupAuthoritiesByUsernameQuery</tt>.     *     * @return a list of GrantedAuthority objects for the user     */    protected List<GrantedAuthority> loadGroupAuthorities(String username) {        return getJdbcTemplate().query(groupAuthoritiesByUsernameQuery, new String[] {username}, new RowMapper<GrantedAuthority>() {            public GrantedAuthority mapRow(ResultSet rs, int rowNum) throws SQLException {                 String roleName = getRolePrefix() + rs.getString(3);                 GrantedAuthorityImpl authority = new GrantedAuthorityImpl(roleName);                 return authority;            }        });    }    /**     * Can be overridden to customize the creation of the final UserDetailsObject which is     * returned by the <tt>loadUserByUsername</tt> method.     *     * @param username the name originally passed to loadUserByUsername     * @param userFromUserQuery the object returned from the execution of the     * @param combinedAuthorities the combined array of authorities from all the authority loading queries.     * @return the final UserDetails which should be used in the system.     */    protected UserDetails createUserDetails(String username, UserDetails userFromUserQuery,            List<GrantedAuthority> combinedAuthorities) {        String returnUsername = userFromUserQuery.getUsername();        if (!usernameBasedPrimaryKey) {            returnUsername = username;        }        logger.debug("username = " + returnUsername);        logger.debug("password = " + userFromUserQuery.getPassword());        return new Account(returnUsername, userFromUserQuery.getPassword(), 0,                0, 0, 0,combinedAuthorities);    }    /**     * Allows the default query string used to retrieve authorities based on username to be overridden, if     * default table or column names need to be changed. The default query is {@link     * #DEF_AUTHORITIES_BY_USERNAME_QUERY}; when modifying this query, ensure that all returned columns are mapped     * back to the same column names as in the default query.     *     * @param queryString The SQL query string to set     */    public void setAuthoritiesByUsernameQuery(String queryString) {        authoritiesByUsernameQuery = queryString;    }    protected String getAuthoritiesByUsernameQuery() {        return authoritiesByUsernameQuery;    }    /**     * Allows the default query string used to retrieve group authorities based on username to be overridden, if     * default table or column names need to be changed. The default query is {@link     * #DEF_GROUP_AUTHORITIES_BY_USERNAME_QUERY}; when modifying this query, ensure that all returned columns are mapped     * back to the same column names as in the default query.     *     * @param queryString The SQL query string to set     */    public void setGroupAuthoritiesByUsernameQuery(String queryString) {        groupAuthoritiesByUsernameQuery = queryString;    }    /**     * Allows a default role prefix to be specified. If this is set to a non-empty value, then it is     * automatically prepended to any roles read in from the db. This may for example be used to add the     * <tt>ROLE_</tt> prefix expected to exist in role names (by default) by some other Spring Security     * classes, in the case that the prefix is not already present in the db.     *     * @param rolePrefix the new prefix     */    public void setRolePrefix(String rolePrefix) {        this.rolePrefix = rolePrefix;    }    protected String getRolePrefix() {        return rolePrefix;    }    /**     * If <code>true</code> (the default), indicates the {@link #getUsersByUsernameQuery()} returns a username     * in response to a query. If <code>false</code>, indicates that a primary key is used instead. If set to     * <code>true</code>, the class will use the database-derived username in the returned <code>UserDetails</code>.     * If <code>false</code>, the class will use the {@link #loadUserByUsername(String)} derived username in the     * returned <code>UserDetails</code>.     *     * @param usernameBasedPrimaryKey <code>true</code> if the mapping queries return the username <code>String</code>,     *        or <code>false</code> if the mapping returns a database primary key.     */    public void setUsernameBasedPrimaryKey(boolean usernameBasedPrimaryKey) {        this.usernameBasedPrimaryKey = usernameBasedPrimaryKey;    }    protected boolean isUsernameBasedPrimaryKey() {        return usernameBasedPrimaryKey;    }    /**     * Allows the default query string used to retrieve users based on username to be overridden, if default     * table or column names need to be changed. The default query is {@link #DEF_USERS_BY_USERNAME_QUERY}; when     * modifying this query, ensure that all returned columns are mapped back to the same column names as in the     * default query. If the 'enabled' column does not exist in the source database, a permanent true value for this     * column may be returned by using a query similar to     * <pre>     * "select username,password,'true' as enabled from users where username = ?"     * </pre>     *     * @param usersByUsernameQueryString The query string to set     */    public void setUsersByUsernameQuery(String usersByUsernameQueryString) {        this.usersByUsernameQuery = usersByUsernameQueryString;    }    protected boolean getEnableAuthorities() {        return enableAuthorities;    }    /**     * Enables loading of authorities (roles) from the authorities table. Defaults to true     */    public void setEnableAuthorities(boolean enableAuthorities) {        this.enableAuthorities = enableAuthorities;    }    protected boolean getEnableGroups() {        return enableGroups;    }    /**     * Enables support for group authorities. Defaults to false     * @param enableGroups     */    public void setEnableGroups(boolean enableGroups) {        this.enableGroups = enableGroups;    }}


页面的制作,可以自己添加几个简单的进行尝试,注意login表单里面用户名的name要用j_username,password的name要用j_password,action的url要写"<%=path %>/j_spring_security_check"

经过如上配置,所有的role_开头的资源都会被保护,需要用户登录,且拥有"ROLE_USER"的权限才可以查阅,我们可以自己去数据库添加用户添加权限来进行登录。

我的主要参考是Spring Security-3.0.1中文官方文档,然后查看Spring Security包里面的源码会有很大的帮助。

热点排行