Spring Security helloworld

Spring Security 系列教程-Hello World Spring Security 系列教程一. Hello WorldSpring Security,是Spring提供的权限控制框架,配合Spring Boot,通过简单的配置,就可以实现强大的功能。本次教程,是Spring Security 系列教程的开端,将实现一个spring security的 “hello world”。 本次教程,将使用到以下的框架:Spring Boot Sprin 阅读详情

首先,不好意思,这篇文字不会太好,因为实在没有太好的资料去查阅,有个官方文档英文的,试试硬着头皮看看吧,然后再整理篇。。。


0Spring Security介绍

Spring Security是一种为基于Spring的应用程序提供说明性安全保护框架。
他提供了全面的安全性解决方案,同时在Web请求级和方法调用级处理身份确认和授权。

在过去Spring Security被成为Acegi Security。

在保护Web应用程序时,采用了filter来拦截Servlet请求。
还可以保护方法调用在一个较低层的级别上执行安全措施,只用Spring AOP来代理对象。

主要使用了5个组件来实施安全措施:
安全拦截器:
认证管理器、访问决策管理器、运行身份管理器、调用后管理器

安全拦截器:只负责上锁拦截你的请求;
认证管理器:一个灵活的认证策略,用于判定你是谁;
访问决策管理器:一旦Spring Security确定了你是谁,他就必须决定你是否对受保护资源有访问授权;
运行身份管理器:运行身份管理器可以用来使用另一个身份替换你的身份,从而允许你访问应用程序内部更深处的受保护对象。
调用后管理器:确保你拿走的数据是否在允许范围之内。

1加强URL访问安全

问题:
控制一些私密的URL被访问。

解决方案:
首先在web.xml注册过滤器DelegatingFilterProxy,他会转到Spring上下文中配置的过滤器。

如果你想使用简单的方式,可以设置元素的autoconfig属性为true,这样Spring Security将自动注册和配置以下几个基本的安全服务:
·基于表单的登录服务:提供保护应用登录表单的默认界面。
·注销服务:提供一个映射到用于用户退出应用的URL的处理程序。
·HTTP基本验证:处理HTTP请求头标中存在的基本验证凭据,还能用于验证远程协议的Web服务发出的验证请求。
·匿名登录:为匿名用户指派一个角色并授予权限,可以将匿名用户作为常规用户处理。
·Remember-me支持:在多个浏览器会话中记忆用户的身份,通常在用户浏览器中存储一个Cookie来实现。
·Servlet API集成:允许通过标准Servlet API如HttpServletRequest.isUserInRole()和HttpServletRequest.getUserPrincipal(),访问Web应用中的安全信息。


工作原理:

以一个demo为例:
一个留言板,让用户粘贴他们的信息。

domain:

public class Message {
    private Long id;
    private String author;
    private String title;
    private String body;

service:
public interface MessageBoardService {
    public List<Message> listMessage();
    public void postMessage(Message message);
    public void deleteMessage(Long id);
    public Message findMessageById(Long id);
}

public class MessageBoardServiceImpl implements MessageBoardService {
    private Map<Long, Message> messages = new LinkedHashMap<Long, Message>();

    @Override
    public List<Message> listMessage() {
        return new LinkedList<Message>(messages.values());
    }

    @Override
    public synchronized void postMessage(Message message) {
        message.setId(System.currentTimeMillis());
        messages.put(message.getId(), message);
    }

    @Override
    public synchronized void deleteMessage(Long id) {
        messages.remove(id);
    }

    @Override
    public Message findMessageById(Long id) {
        return messages.get(id);
    }

}

我们要使用Spring MVC
pom:
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>${spring.version}</version>
</dependency>


<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-core</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-ldap</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-taglibs</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-acl</artifactId>
    <version>${spring.version}</version>
</dependency>

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <display-name>nongfu888</display-name>

    <!--*********************begin:spring的配置****************** -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:META-INF/spring/beans.xml</param-value>
    </context-param>
    <context-param>
        <param-name>request.charsetencoding</param-name>
        <param-value>GBK</param-value>
    </context-param>

    <!-- 对Spring容器进行实例化 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:META-INF/spring/springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.jsp</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.tile</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

在Web层次配置文件springmvc.xml,你定义了一个视图解析器,将视图名称解析为/WEB-INF/jsp/目录中的JSP文件。
然后配置你的控制器:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    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/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">
  <context:component-scan base-package="cn.partner4java.controller" />
  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/jsp/" />
    <property name="suffix" value=".jsp" />
  </bean>
</beans>        

服务层配置文件service.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <bean id="messageBoardService" class="com.partner4java.demo.service.MessageBoardServiceImpl" />
</beans>       

创建控制器和页面视图:
@Controller
@RequestMapping("/messageList*")
public class MessageListController {
    private MessageBoardService messageBoardService;

    @Autowired
    public void setMessageBoardService(MessageBoardService messageBoardService) {
        this.messageBoardService = messageBoardService;
    }

    @RequestMapping(method = RequestMethod.GET)
    public String generateList(Model model) {
        model.addAttribute("messages", messageBoardService.listMessage());
        return "messageList";
    }
}

然后就是创建界面:
/webapp/WEB-INF/jsp/messageList.jsp

 ....然后又添加了添加和删除类。
 
 
 现在开始做我们保护URL的事情:
 
首先要拦截请求
使用Servlet过滤器,保护Web应用程序。

代理Spring Security的过滤器:
代理Servlet过滤器:
FilterToBeanFactory是一个特殊的Servlet过滤器,他本身做的工作并不多,而是将自己的工作委托给Spring应用程序上下文中的一个Bean来完成。(已被DelegatingFilterProxy取代)
 
   <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>

被委托的Bean几乎和其他的Servlet过滤器一样,实现Filter,但是他在Spring配置文件中不是web.xml中。
FilterChainProxy:
可以被配置来同时把几个过滤器连接在一起。

看看上下文中的bean:

The order that filters are defined in the chain is very important. Irrespective of which filters you are actually
using, the order should be as follows:
1.ChannelProcessingFilter, because it might need to redirect to a different protocol
确保正通过HTTP或HTTPS发送一个请求

2.ConcurrentSessionFilter, because it doesn't use any SecurityContextHolder functionality
but needs to update the SessionRegistry to reflect ongoing requests from the principal
确保一个用户没有在设置的时间内同时登录

3.SecurityContextPersistenceFilter,  so  a  SecurityContext  can  be  set  up  in  the
SecurityContextHolder  at  the  beginning  of  a  web  request,  and  any  changes  to  the
SecurityContext can be copied to the HttpSession when the web request ends (ready for use with
the next web request)

4.Authentication  processing  mechanisms  -  UsernamePasswordAuthenticationFilter,
CasAuthenticationFilter,  BasicAuthenticationFilter  etc  -  so  that  the
SecurityContextHolder can be modified to contain a valid Authentication request token

5.The SecurityContextHolderAwareRequestFilter,  if  you  are  using  it  to  install  a  Spring
Security aware HttpServletRequestWrapper into your servlet container
为servlet请求增加一个请求外壳

6.The  JaasApiIntegrationFilter,  if  a  JaasAuthenticationToken  is  in  the
SecurityContextHolder  this  will  process  the  FilterChain  as  the  Subject  in  the
JaasAuthenticationToken

7.RememberMeAuthenticationFilter,  so  that  if  no  earlier  authentication  processing  mechanism
updated the SecurityContextHolder, and the request presents a cookie that enables remember-me
services to take place, a suitable remembered Authentication object will be put there

8.AnonymousAuthenticationFilter,  so  that  if  no  earlier  authentication  processing  mechanism
updated the SecurityContextHolder, an anonymous Authentication object will be put there

9.ExceptionTranslationFilter, to catch any Spring Security exceptions so that either an HTTP error
response can be returned or an appropriate AuthenticationEntryPoint can be launched

10.FilterSecurityInterceptor, to protect web URIs and raise exceptions when access is denied
充当安全拦截器角色,决定是否允许访问某一受保护的资源
    
    
要加在SpringMVC的Servlet之前。    

然后,我们配置一个最简单的控制访问策略
<?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.1.xsd">

    <!-- auto-config="true"典型的基本应用方式 -->
    <http auto-config="true">
        <intercept-url pattern="/messageList*" access="ROLE_USER,ROLE_GUEST" />
        <intercept-url pattern="/messagePost*" access="ROLE_USER" />
        <intercept-url pattern="/messageDelete*" access="ROLE_ADMIN" />
    </http>

    <authentication-manager>
        <authentication-provider>
            <user-service>
                <user name="admin" password="secret" authorities="ROLE_ADMIN,ROLE_USER" />
                <user name="user1" password="1111" authorities="ROLE_USER" />
            </user-service>
        </authentication-provider>
    </authentication-manager>


</beans:beans>
这样就可以访问了,这个配置Spring配置文件要放到web.xml的contextConfigLocation里,
可以说下的是auto-config="true",已默认的策略进行访问控制,包括登录界面都会给你提供默认的,然后其中的另外两个标签没有什么好说的,一个是权限管理,一个是用户管理。

也许你想说,我们一般登录界面是自己写的,然后用户权限也是放到库里的....


2登录到Web应用

自定义一个网页作为登录界面、HTTP基本验证、remember-me登录等

去掉自动配置

<http>
    <intercept-url pattern="/messageList*" access="ROLE_USER,ROLE_GUEST" />
    <intercept-url pattern="/messagePost*" access="ROLE_USER" />
    <intercept-url pattern="/messageDelete*" access="ROLE_ADMIN" />
    <form-login login-page="/login.jsp" default-target-url="/messageList"
        authentication-failure-url="/login.jsp?error=true" />
    <logout logout-success-url="/login.jsp" />
    <remember-me />
</http>
HTTP基本验证:<http-basic/>
基于表单的登录:<form-login/>
登录失败:
authentication-failure-url="/login.jsp?error=true"
前台展示${sessionScope["SPRING_SECURITY_LAST_EXCEPTION"].message}
注销登录:<logout logout-success-url="/login.jsp" />
<a href="<c:url value="/j_spring_security_logout" />">退出登录</a>
匿名登录:<anonymous username="guest" granted-authority="ROLE_GUEST"/>可以自定义匿名用户的用户名和权限
Remember-Me支持:<remember-me /> <input type="checkbox" name="_spring_security_remember_me" />


3验证用户

解决用户:
采取了本地内存验证和数据库验证,还有LDAP方式。还额外提供了缓存支持。

工作原理:

首先说新的简化方式:

本地内存方式:

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="admin" password="secret" authorities="ROLE_ADMIN,ROLE_USER" />
            <user name="user1" password="1111" authorities="ROLE_USER" />
        </user-service>
    </authentication-provider>
</authentication-manager>
properties方式:
<authentication-manager>
    <authentication-provider>
        <user-service properties="classpath:META-INF/spring/users.properties"/>
    </authentication-provider>
</authentication-manager>


依靠数据库验证用户:
<jdbc-user-service data-source-ref="dataSource"/>
简单方式:
CREATE TABLE `users` (
  `username` varchar(10) NOT NULL,
  `password` varchar(32) NOT NULL,
  `enabled` smallint(6) DEFAULT NULL,
  PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `authorities` (
  `username` varchar(10) NOT NULL,
  `authority` varchar(10) NOT NULL,
  KEY `[OwnerName]_fk[num_for_dup]` (`username`),
  CONSTRAINT `[OwnerName]_fk[num_for_dup]` FOREIGN KEY (`username`) REFERENCES `users` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `users` (`username`, `password`, `enabled`) VALUES
  ('admin', 'secret', 1),
  ('user1', '1111', 1),
  ('user2', '2222', 1);
 
INSERT INTO `authorities` (`username`, `authority`) VALUES
  ('admin', 'ROLE_ADMIN'),
  ('user1', 'ROLE_USER'),
  ('admin', 'ROLE_USER'),
  ('user2', 'ROLE_USER');  

也可以自己制定数据库:
<authentication-manager>
    <authentication-provider>
        <!--<user-service properties="classpath:META-INF/spring/users.properties"/> -->
        <jdbc-user-service data-source-ref="dataSource"
            users-by-username-query="
        select username,password,'true' as enabled from member where username=?"
            authorities-by-username-query="select m.username,mr.role as authorities from from member m,member_role mr where
            m.username=? and m.id = mr.member_id" />
    </authentication-provider>
</authentication-manager>
CREATE TABLE `member` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(20) NOT NULL,
  `password` varchar(32) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

CREATE TABLE `member_role` (
  `member_id` int(11) NOT NULL,
  `role` varchar(10) NOT NULL,
  KEY `member_id` (`member_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `member` (`id`, `username`, `password`) VALUES
  (1, 'admin', 'secret'),
  (2, 'user', '1111');

INSERT INTO `member_role` (`member_id`, `role`) VALUES
  (1, 'ROLE_ADMIN'),
  (1, 'ROLE_USER'),
  (2, 'ROLE_USER');  

为了减少对数据库的压力还可以添加缓存:
    <bean id="cacheManager"
        class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="classpath:ehcache.xml" />
    </bean>
    <bean id="userEhCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
        <property name="cacheManager" ref="cacheManager" />
        <property name="cacheName" value="userCache" />
    </bean>
    <bean id="userCache"
        class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache">
        <property name="cache" ref="userEhCache" />
    </bean>  

    <authentication-manager>
        <authentication-provider>
            <!--<password-encoder hash="md5"/> -->
            <!--<user-service properties="classpath:META-INF/spring/users.properties"/> -->
            <jdbc-user-service data-source-ref="dataSource"
                users-by-username-query="
            select username,password,'true' as enabled from member where username=?"
                authorities-by-username-query="select m.username,mr.role as authorities from member m,member_role mr where
                m.username=? and m.id = mr.member_id"
                cache-ref="userCache" />
        </authentication-provider>
    </authentication-manager>  

   
authentication-manager是一种简单标签方式,原始bean标签方式为:
(以下只做参考,可忽略)
一般会以登录的方式提供身份认证,但是也会存在例外。

认证管理器负责确定用户的身份,认证管理器由AuthenticationManager接口定义。
org.springframework.security.authentication.AuthenticationManager:
只有一个方法Authentication authenticate(Authentication authentication)
将会尝试利用org.springframework.security.core.Authentication对象来验证用户身份。
如果认证成功,authenticate会返回一个完整的Authentication对象,其中包括用户已被授予的权限信息,如果验证失败抛出AuthenticationException。

1、配置ProviderManager:
ProviderManager是认证管理器的一种实现,他将验证身份的责任委托给一个或多个认证提供者。
ProviderManager的用途是使你能够根绝多个身份管理源来认定用户。

他不依靠自己实现认证,而是逐一认证提供者的集合,直到某一个认证提供者能够成功的验证该用户的身份。
<bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
    <constructor-arg name="providers">
        <list>
            <ref bean=""/>
        </list>
    </constructor-arg>
</bean>    



列表值接口:org.springframework.security.authentication.AuthenticationProvider
AuthenticationProvider接口与前面的AuthenticationManager接口没有什么太大不同,他们都有一个处理认证authenticate()方法。实际上,可以把认证提供者看做是第二等级的认证管理器。

org.springframework.security.authentication.AnonymousAuthenticationProvider:
以匿名用户方式验证用户。在即使用户尚未登录,扔需要用户令牌时,会比较有用。

org.springframework.security.authentication.dao.DaoAuthenticationProvider:
从数据库中获取用户信息,包括用户名和密码。

org.springframework.security.authentication.jaas.JaasAuthenticationProvider:
从JAAS登录配置中获取用户信息。

org.springframework.security.authentication.RememberMeAuthenticationProvider:
验证某一之前验证过并且被记住的用户的身份。这使得无需提示输入用户名和登录即自动登录某一用户成为可能。

org.springframework.security.authentication.rcp.RemoteAuthenticationProvider:
根据远程服务验证用户身份。

org.springframework.security.authentication.TestingAuthenticationProvider:
用于单元测试。自动认为一个TestingAuthenticationToken是有效的。不应用于生产环境。

org.springframework.security.access.intercept.RunAsImplAuthenticationProvider:
针对身份已经被运行身份管理器替换的用户进行认证。


2、根据数据库验证身份
DaoAuthenticationProvider是一个简单的认证提供者,他使用数据库对象(DAO)来从关系数据库中检索用户信息。
    <bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
        <property name="userDetailsService" ref=""/>
    </bean>    
这里的userDetailsService属性被用来指定将用于从数据库中检索用户信息的那个Bean。
这个用户期望org.springframework.security.core.userdetails.UserDetailsService的一个实例。
public interface UserDetailsService {
    UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}

一种方式使用内存Dao:
org.springframework.security.provisioning.InMemoryUserDetailsManager
Non-persistent implementation of UserDetailsManager which is backed by an in-memory map.
Mainly intended for testing and demonstration purposes, where a full blown persistent system isn't required.
非持久的UserDetailsManager的实施,这是内存中的地图支持。
主要用于试验和示范的目的,不需要在一个完全成熟的持久系统。


另一种方式 声明一个JDBC DAO:
    <bean id="userDetailsService"
        class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
        <property name="dataSource" ref="dataSource" />
    </bean>

他内部假设了一些query语句:
    public static final String DEF_USERS_BY_USERNAME_QUERY =
            "select username,password,enabled " +
            "from users " +
            "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";

    private String authoritiesByUsernameQuery;
    private String groupAuthoritiesByUsernameQuery;
    private String usersByUsernameQuery;

那么也就是这三个查询有默认值,当然你可以可以自己配置。
    <bean id="userDetailsService"
        class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
        <property name="dataSource" ref="dataSource" />
        <property name="usersByUsernameQuery">
            <value>
                select email as username,password,enabled
                    from motorist
                    where email = ?
            </value>
        </property>
        <property name="authoritiesByUsernameQuery">
            <value>
                select email as username,privilege as authority  
                    from motorist_privileges mp,motorist m
                    where mp.motorist_id = m.id
                    and m.email = ?
            </value>
        </property>
    </bean>

使用加密的密码:
DaoAuthenticationProvider中配置加密方式org.springframework.security.authentication.encoding.PasswordEncoder

org.springframework.security.authentication.encoding.Md5PasswordEncoder:
在密码上执行“信息摘要”(MD5)编码。
org.springframework.security.authentication.encoding.PlaintextPasswordEncoder:
在密码上不执行任何编码,照原样返回他。
org.springframework.security.authentication.encoding.ShaPasswordEncode:
在密码上执行“安全散列算法”(SHA)编码。
org.springframework.security.authentication.encoding.LdapShaPasswordEncoder:
使用LDAP SHA和salted-SHA(SSHA)编码技术编码密码。
    <bean id="daoAuthenticationProvider"
        class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
        <property name="userDetailsService" ref="userDetailsService" />
        <property name="passwordEncoder">
            <bean
                class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />
        </property>
    </bean>

你还将需要为编码器设置一个种子源(salt source)。一个种子源为所用的编码技术提供种子(salt),或者称加密密钥。
org.springframework.security.authentication.dao.SaltSource:
org.springframework.security.authentication.dao.SystemWideSaltSource:对所有的用户提供相同的种子。
org.springframework.security.authentication.dao.ReflectionSaltSource:利用用户的User对象中某个指定属性的反射来生成种子。
    <bean id="daoAuthenticationProvider"
        class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
        <property name="userDetailsService" ref="userDetailsService" />
        <property name="passwordEncoder">
            <bean
                class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />
        </property>
        <property name="saltSource">
            <bean class="org.springframework.security.authentication.dao.ReflectionSaltSource">
                <property name="userPropertyToUse" value="userName"/>
            </bean>
        </property>
    </bean>



4做出访问控制决策
 
问题:
在验证过程中,应用将把一组权限授予成功验证的用户。
当这个用户试图访问应用中的资源时,应用必须用授予的权限或者其他特性决定哪些资源可以访问。

解决方案:
org.springframework.security.access.AccessDecisionManager:
访问决策投票:
org.springframework.security.access.vote.AffirmativeBased:
只要有一个投票者投票赞成授予访问权,就允许访问。
org.springframework.security.access.vote.ConsensusBased:
只要大多数投票允许访问,就允许访问。
org.springframework.security.access.vote.UnanimousBased:
只有都赞成访问的时候,才可以访问。

默认情况下如果不配置会给一个默认配置。

你还可以自定义访问策略,只需要实现AccessDecisionManager。
    <!-- 决定如何投票 -->
    <bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter">
        <!-- 将只针对GROUP_为前缀的权限进行授权投票,默认为"ROLE_" -->
        <property name="rolePrefix" value="GROUP_" />
    </bean>

    <!-- 访问决策管理器 -->
    <bean id="accessDecisionManager"
        class="org.springframework.security.access.vote.AffirmativeBased">
        <constructor-arg name="decisionVoters">
            <list>
                <ref bean="roleVoter" />
            </list>
        </constructor-arg>
        <!-- 沉默即同意的政策 -->
        <!--<property name="allowIfAllAbstainDecisions" value="true"/> -->
    </bean>


5加强方法调用的安全

问题:
有时候你可能想具体控制到某个方法上。

解决方案:

三种方式:
1、在Bean定义中嵌入一个<se:intercept-methods>,如:

<bean id="messageBoardService" class="com.partner4java.demo.service.MessageBoardServiceImpl">
    <se:intercept-methods access-decision-manager-ref="accessDecisionManager">
        <se:protect access="ROLE_USER,ROLE_GUEST" method="com.partner4java.demo.service.MessageBoardService.listMessage"/>
    </se:intercept-methods>
</bean>


2、利用AOP和Security提供的xml方式
<global-method-security access-decision-manager-ref="accessDecisionManager">
    <protect-pointcut access="ROLE_USER,ROLE_GUEST" expression="execution(* com.partner4java.demo.service.*Service.list*(..))"/>
    <protect-pointcut access="ROLE_USER" expression="execution(* com.partner4java.demo.service.*Service.post*(..))"/>
</global-method-security>

3、注解
@Override
@Secured({"ROLE_USER","ROLE_GUEST"})
public List<Message> listMessage() {
    return new LinkedList<Message>(messages.values());
}


6处理视图中的安全性

问题:
有时,你可能希望在Web应用的视图中显示用的验证信息,例如角色名称和授权。此外,你还希望根据用户授权有条件的显示视图内容。

解决方案:
Spring Security提供了一个JSP标记库。

显示验证信息:
<security:authentication/>标记暴漏当前用户的Authentication,供你显示其属性。
你可以在property属性中指定属性名称和属性路径。

例如:<security:authentication property="name"/>显示用户的角色名称。

<security:authentication property="authorities" var="authorities"/>
<ul>
    <c:forEach items="${authorities }" var="authority">
        <li>${authority.authority }</li>
    </c:forEach>
</ul>


遍历权限。


有条件地显示视图内容:
如果你希望根据用户授权有条件的显示视图内容,可以使用
<security:authorize ifAnyGranted="ROLE_ADMIN">
    亲
</security:authorize>
还有ifAllGranted="" ifNotGranted="" ,如词义。


7处理领域对象安全性

问题:
有时候,你可能有复杂的安全需求,需要在领域对象的级别上处理安全性。
这意味着你必须让每个领域对象对不同的角色有不同的访问属性。


解决方案:
Spring Security提供一个名为ACL的模块,使每个领域对象都有自己的访问控制列表(ACL)。
(简单说,我们前面是保护方法和显示块,现在我们是来保护具体数据)
ACL包含一个与领域对象关联的对象标识(object identity),还保存多个访问控制项(Access Control Entries ,ACEs),每个控制项包含下面两个核心部分。
·权限:ACE的权限由一个特别的位屏蔽代表,每位的值用于特定类型的权限。
BasePermission预先定义了5种基本权限的常量值供你使用:READ(读,第0位或者整数1)、WRITE(写,第1位或者整数2)、CREATE(创建,第2位或者整数4)、DELETE(删除,第3位或者整数8)以及ADMINISTRATION(管理,第4位或者整数16)。你还可以自行定义其他未使用的位。
·安全标识(SID):每个ACE包含特定的SID的权限。SID可以是一个与权限关联的角色(PrincipalSid)或者授权(GrantedAuthoritySid)。


工作原理:

设置ACL服务

两个定义ACL服务操作的接口:AclService和MutableAclService。
AclService定义读取ACL的操作。
MutableAclService是AclService的一个子接口,定义用于创建、更新和删除ACL的操作。
http://blog.youkuaiyun.com/kongxx/article/details/5884352
http://hi.baidu.com/danghj/item/0f6be1c4ab95af7489ad9ed0

@Override
@Transactional
@Secured({ "ROLE_USER" })
public synchronized void postMessage(Message message) {
    message.setId(System.currentTimeMillis());
    messages.put(message.getId(), message);

    ObjectIdentity oid = new ObjectIdentityImpl(Message.class,
            message.getId());
    MutableAcl acl = mutableAclService.createAcl(oid);
    acl.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(
            message.getAuthor()), true);
    acl.insertAce(1, BasePermission.DELETE, new GrantedAuthoritySid("ROLE_ADMIN"), true);
    acl.insertAce(2, BasePermission.READ, new GrantedAuthoritySid("ROLE_USER"), true);
    mutableAclService.updateAcl(acl);
}

@Override
@Secured({ "ROLE_ADMIN","ACL_MESSAGE_DELETE" })
public synchronized void deleteMessage(Long id) {
    messages.remove(id);
    ObjectIdentity oid = new ObjectIdentityImpl(Message.class, id);
    mutableAclService.deleteAcl(oid, false);
}



为领域对象维护ACL:
在你的后端服务和DAO中,你可以用前面通过依赖注入定义的ACL服务,为领域对象维护ACL。
对于你的留言板,你必须在留言张贴时为其创建ACL,并在留言删除时删除该ACL:

<!-- 标记查询指定的领域对象ACL,检查当前用户有无指定的权限。这个标记只在用户具有一个必要权限时显示其主体信息。8,16代表前面说的DELETE(删除,第3位或者整数8)以及ADMINISTRATION(管理,第4位或者整数16) -->
<security:accesscontrollist domainObject="${message}" hasPermission="8,16">
    <tr>
        <td colspan="2">
            <a href="messageDelete?messageId=${message.id}">Delete</a>
        </td>
    </tr>
</security:accesscontrollist>


但是上面标签:AccessControlListTag里的PermissionEvaluator报空指针,不知道为什么

过滤返回结果:
<bean id="afterAclRead" class="org.springframework.security.acls.afterinvocation.AclEntryAfterInvocationProvider">
    <security:after-invocation-provider/>
    <constructor-arg ref="aclService"/>
    <constructor-arg>
        <list>
            <util:constant
                static-field="org.springframework.security.acls.domain.BasePermission.ADMINISTRATION" />
            <util:constant
                static-field="org.springframework.security.acls.domain.BasePermission.DELETE" />
        </list>
    </constructor-arg>
</bean>
<bean id="afterAclCollectionRead" class="org.springframework.security.acls.afterinvocation.AclEntryAfterInvocationCollectionFilteringProvider">
    <security:after-invocation-provider/>
    <constructor-arg ref="aclService"/>
    <constructor-arg>
        <list>
            <util:constant
                static-field="org.springframework.security.acls.domain.BasePermission.ADMINISTRATION" />
            <util:constant
                static-field="org.springframework.security.acls.domain.BasePermission.DELETE" />
        </list>
    </constructor-arg>
</bean>


bean中嵌入一个<security:after-invocation-provider/>,就能注册一个自定义后调用提供者.
然后就可以在权限组中加入AFTER_ACL_COLLECTION_READ和AFTER_ACL_READ到上面的权限注解中.
(后处理没验证)

源码下在地址:http://download.youkuaiyun.com/detail/partner4java/4538585

Spring Security 实例 一个简单的HelloWorld 关于spring安全实例 因为Spring Security是建立在Spring的基础之上的, 这个简陋的页面是Spring Security自动生成的,一来为了演示的方便,二来避免用户自己编写登陆页面时犯错,Spring Security为了避免可能出现的风险,连测试用的登录页面都自动生成出来了。在这里我们就省去编写登陆页面的步骤,直接使用默认生成的登录页面进行演示吧。 立即下载

相关推荐

Spring-Security-3-HelloWorld 实例简单代码

Spring-Security-3-HelloWorld 实例简单代码

从HelloWorld深入源码了解SpringSecurity底层逻辑

为什么引⼊之后没有任何配置所有请求就要认证呢?这就不得不提SpringBoot的默认配置类, 这个类是⾃动配置类,通过这个源码得知,默认情况下对所有请求进⾏权限控制。这就是为什么在引⼊ Spring Security 中没有任何配置情况下,请求会被拦截的原因!classpath中存在条件⼆ 没有⾃定义默认情况下,条件都是满⾜的。这个类极其重要,核⼼配置都在这个类中如果要对进⾏⾃定义配置,就要⾃定义这个类实例,通过覆盖类中⽅法达到修改默认配置的⽬的对于。

写写平时的技术与感想 2144

宝塔面板磁盘扩容后不生效?5步搞定Linux服务器磁盘空间更新(附详细命令)

本文详细解析了Linux服务器磁盘扩容后宝塔面板显示不生效的常见问题。通过理解磁盘、分区、文件系统三层逻辑,提供5步解决方案:检查磁盘状态、安装growpart工具、扩展分区、使用resize2fs命令扩展文件系统,并最终验证结果。文中附有详细命令和针对XFS、LVM等进阶场景的指南,帮助用户彻底解决磁盘空间更新问题。

weixin_29271263的博客 128

SpringSecurity系列,第一章:Hello World

SpringSecurity系列,第一章:Hello World 之前项目一直在用shiro,对SpringSecurity的了解比较少。正好这段时间项目中用到了S...

倚书依杖听河流博客 219

伺服驱动器485通信

485通信使用方法,485通信在上位机和伺服驱动器之间的应用,根据需要驱动电机旋转。

haipi511715316的博客 1万+

vCenter Server出现no healthy upstream的解决方法

可以通过"VMware vCenter Server Management(服务)"来排查问题,在网页里面找到“服务”模块,会发现有很多服务没有启动起来,而且手动启动也无法启动。7.0 地址后,页面出现“no healthy upstream”,无法正常登录vCenter,重启后依旧如此,该故障的前提是没有对vCenter做过任何配置,如下图所示。于是用命令查询是否有证书过期,发现真有多个服务依赖的证书在当天早上过期。使用如下命令尝试打开服务发现不分服务可以打开,不分服务无法打开。

1万+

Spring Security入门5:创建首个HelloWorld项目

本文讲解如何在本地创建最基础的Spring Security项目,实现Hello World接口的调用和鉴权,以及如何使用HTTP Basic身份验证调用端点。

Designer 小郑的技术博客 2245

抖音最新风控体系研究

小编从技术角度对抖音的风控史和落地目标,跟大家聊一聊抖音,包括海外版抖音TikTok的现状与生态。 1、非常非常早的时期,抖音刚出来的时候,没有任何封禁,这个阶段,导入一个开发库,加上一个请求头,咵咵咵的数据随便拿。 2、2018-2019年,抖音加入了设备id和xg机制,在绝大多数的接口中,携带了设备id参数,同时在请求头中加入了xg,如今的apk市场,能追溯到的最早xg是0200打头的,而小编见过的最早的xg是0000打头的。这个时期的接口,这些参数都还只是预设,没有实际的用处,设备随便写,

qq517348412的博客 1万+

spring-security之 HelloWorld (一)

简介: 在本教程中,我们将向您展示如何通过Spring Security使用Spring MVC的Web应用程序来集成一个URL访问。使用 Spring Security 来实现一个“admin”页面的内容后,验证用户输入正确的“用户名”和“密码”。 版本介绍:     <project.build.sourceEncoding>UTF-8&l...

仗剑走天涯 248

Linux内核4.14版本——drm框架分析(1)——drm简介

本文介绍了DRM架构的发展历史、驱动框架以及简单示例,旨在帮助读者了解DRM架构的形成、功能流程实现。

phmatthaus的专栏 2558

基于 YOLOv26 的遥感图像目标检测系统:从原理到模型

本文介绍了基于YOLOv26的遥感图像目标检测系统。YOLOv26凭借端到端设计、轻量化架构和小目标优化能力,有效解决了遥感图像中多尺度目标、复杂背景、小目标检测等挑战。系统采用CSPDarknet骨干网络和FPN+PAN特征融合模块,通过MuSGD优化器和改进损失函数提升训练效果。文章详细阐述了数据预处理、模型训练流程和优化技巧,包括Tile推理和混合精度训练。系统支持多种部署方式,在CPU上推理速度提升43%,能实现高精度、实时性的遥感目标检测,适用于城市规划、农业监测等场景。

一键难忘的博客 571

Spring Security(二):三分钟入门HelloWorld

基于上篇文章的《Spring Security(一):10分钟搭建项目结构》已经清楚了整体的项目结构,本篇文章下面主要介绍如何快速入门 HelloWorld。 1、zjj-security-demo创建启动类ZjjSecurityDemoApplication package com.zjj.security; import org.springframework.boot.Sprin...

zhujunjun6的专栏 197

iqoo11如何获取root权限?

🏆本文收录于专栏,主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家!持续更新中,up!up!up!!

**My Coding Family** 5849

spring security 3.2: HelloWorld

此文章只为记录一下自己spring-security的配置,同时让与我一样的新手参考一下。 Eclipse版本--------------Luna Service Release 1(4.4.1) spring-security版本-----3.2.3.RELEASE.jar 系统OS-------------------window 7 旗舰版 JDK版本--------------

Flow_Snow的专栏 878

【科研数据获取】根据Excel表个中的企业/公司信息批量获取经纬度坐标,并进行地图可视化

批量获取企业/公司的经纬度坐标,并进行地图可视化1 需求2 实现途径3 需求逐步实现 1 需求 在做项目的时候,老板或者项目答辩时候甲方最喜欢看到的就是可视化结果,尤其是涉及到地图可视化。很多时候会遇到企业/公司的数据,想要做地图可视化,必不可少的就是要获取它们具体地址:第一种就是像查户口一样精准一下具体的城镇街道,还有一种就是经纬度信息,前一种属于文字内容往往用于管理方面,第二种数字信息多用于数据处理与分析。 2 实现途径 获取地理信息数据,自然需要使用到地图的功能,这里直接采用百度地图的拾取坐标系统,

lys_828的博客 2337

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Helloworld Spring Security Java config页面翻译

本文是本人对Helloworld Spring Security 中java config方式的翻译,由于本人英语水平太差,想通过翻译技术文档的方式来学习英语和技术,同时也可以为以后方便自己查看。 文档的原地址为:http://docs.spring.io/spring-security/site/docs/current/guides/html5//helloworld-javaconfig.

u014053022的博客 615

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

spring security helloworld例子操作

这是一个简单的helloworld 例子,导入就能运行,下面是下载地址: http://download.youkuaiyun.com/detail/u013897204/9618709 运行例子 打开浏览器,输入  http://localhost:8080/SpringSecurityHelloWorld/  就会显示  Hello World! 打开浏览器,输入  http://

平哥的专栏 352

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Spring Security入门学习(一)Helloworld项目

看了一些Spring security的入门帖子/教程,读了文档,发现不是很好理解。还是选择看书吧,这个系列记录一下Spring security in aciton这本书的学习过程。

qq_35059338的博客 773

spring security (-) helloWorld

pom.xml配置文件 &lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache....

火火火 193

Spring Security HelloWorld 例子(Java Config 配置)

Maven 配置 注意:Spring与Security版本要匹配,这一点可以查看Security的编辑依赖项 &lt;!-- Security 安全用 --&gt; &lt;!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core --&gt; &lt;de...

milaobai的博客 1059

spring security 第 1 章 一个简单的HelloWorld

第1章一个简单的HelloWorld Spring Security中可以使用Acegi-1.x时代的普通配置方式,也可以使用从2.0时代才出现的命名空间配置方式,实际上这两者实现的功能是完全一致的,只是新的命名空间配置方式可以把原来需要几百行的配置压缩成短短的几十行。我们的教程中都会使用命名空间的方式进行配置,凡事务求最简。 1.1....

weixin_34259559的博客 189

【spring security oauth2】入门例子(helloworld ) 1- 基础版

概述 Spring Security是一个用于快速实现Web应用安全、认证的框架,可以快速和Spring Boot整合。 开发者可以编写配置类继承WebSecurityConfigurerAdapter类,重写config方法自定义登录页面、登录失败逻辑、权限不足逻辑等,并且可以编写Filter实现更加复杂的图片验证码、短信验证码功能。 Spring Security也可以快速实现OAuth2.0授权服务器和资源服务器。在一个Spring Boot应用中,可以使用@EnableAuthorizationSe

m0_45406092的博客 822

Spring Security 从入门到精通之环境搭建与HelloWorld案例源码详解(二)

spring security 入门环境搭建以及案例详解

GalenGao 405

2021-09-09

Springboot的学习 1.什么是springboot Spring Boot 其实不是什么新的框架,它默认配置了很多框架的使用方式,就像 Maven 整合了所有的 Jar 包,Spring Boot 整合了所有的框架。 2.spring boot的好处 我仅仅只需要非常少的几个配置就可以迅速方便的搭建起来一套 Web 项目或者是构建一个微服务 3.用springboot 写一个hello world maven配置 <id>jdk-1.8</id>

Ocean__5的博客 76
上一篇: 过滤器(filter)helloworld
下一篇: Thread 常搞混的几个概念sleep、wait、yield、interrupt
partner4java
博客等级 码龄17年 481粉丝 183原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值