美食制作网站模板免费下载/竞价托管一般要多少钱
一、IAuthorizationFilter
所有的AuthorizationFilter实现了接口IAuthorizationFilter。如下面的代码片断所示,IAuthorizationFilter定义了一个OnAuthorization方法用于实现授权的操作。作为该方法的参数filterContext是一个表示授权上下文的AuthorizationContext对象, 而AuthorizationContext直接继承自ControllerContext。
1: public interface IAuthorizationFilter
2: {
3: void OnAuthorization(AuthorizationContext filterContext);
4: }
5:
6: public class AuthorizationContext : ControllerContext
7: {
8: public AuthorizationContext();
9: public AuthorizationContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor);
10:
11: public virtual ActionDescriptor ActionDescriptor { get; set; }
12: public ActionResult Result { get; set; }
13: }
AuthorizationContext的ActionDescriptor属性表示描述当前执行Action的ActionDescriptor对象,而Result属性返回一个用于在授权阶段呈现的ActionResult。AuthorizationFilter的执行是ActionInvoker进行Action执行的第一项工作,因为后续的工作(Model绑定、Model验证、Action方法执行等)只有在成功授权的基础上才会有意义。
ActionInvoker在通过执行AuthorizationFilter之前,会先根据当前的Controller上下文和解析出来的用于描述当前Action的ActionDescriptor,并以此创建一个表示授权上下文的AuthorizationContext对象。然后将此AuthorizationContext对象作为参数,按照Filter对象Order和Scope属性决定的顺序执行所有AuthorizationFilter的OnAuthorization。
在所有的AuthorizationFilter都执行完毕之后,如果指定的AuthorizationContext对象的Result属性表示得ActionResult不为Null,整个Action的执行将会终止,而ActionInvoker将会直接执行该ActionResult。一般来说,某个AuthorizationFilter在对当前请求实施授权的时候,如果授权失败它可以通过设置传入的AuthorizationContext对象的Result属性响应一个“401,Unauthrized”回复,或者呈现一个错误页面。
二、AuthorizeAttribute
如果我们要求某个Action只能被认证的用户访问,可以在Controller类型或者Action方法上应用具有如下定义的AuthorizeAttribute特性。AuthorizeAttribute还可以具体限制目标Action可被访问的用户或者角色,它的Users和Roles属性用于指定被授权的用户名和角色列表,中间用采用逗号作为分隔符。如果没有显式地对Users和Roles属性进行设置,AuthorizeAttribute在进行授权操作的时候只要求访问者是被认证的用户。
1: [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited=true, AllowMultiple=true)]
2: public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter
3: {
4: //其他成员
5: public virtual void OnAuthorization(AuthorizationContext filterContext);
6: protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext);
7:
8: public string Roles { get; set; }
9: public override object TypeId { get; }
10: public string Users { get; set; }
11: }
如果授权失败(当前访问者是未被授权用户,或者当前用户的用户名或者角色没有在指定的授权用户或者角色列表中),AuthorizeAttribute会创建一个HttpUnauthorizedResult对象,并赋值给AuthorizationContext的Result属性,意味着会响应一个状态为“401,Unauthorized”的回复。如果采用Forms认证,配置的登录页面会自动被显示。
很多会将AuthorizeAttribute对方法的授权与PrincipalPermissionAttribute等同起来,实际上不但它们实现授权的机制不一样(后者是通过代码访问安全检验实现对方法调用的授权),它们的授权策略也一样。以下面定义的两个方法为例,应用了PrincipalPermissionAttribute的FooOrAdmin意味着可以被帐号为Foo或者具有Admin角色的用户访问,而应用了AuthorizeAttribute特性的方法FooAndAdmin方法则只能被用户Foo访问,而且该用户必须具有Admin角色。也就是说PrincipalPermissionAttribute特性对User和Role的授权逻辑是“逻辑或”,而AuthorizeAttribute 采用的则是“逻辑与”。
1: [PrincipalPermission( SecurityAction.Demand,Name="Foo", Role="Admin")]
2: public void FooOrAdmin()
3: { }
4:
5: [Authorize(Users="Foo", Roles="Admin")]
6: public void FooAndAdmin()
7: { }
除此之外,我们可以将多个PrincipalPermissionAttribute和AuthorizeAttribute应用到同一个类型或者方法上。对于前者,如果当前用于通过了任意一个PrincipalPermissionAttribute特性的授权就有权调用目标方法;对于后者来说,意味着需要通过所有AuthorizeAttribute特性的授权在具有了调用目标方法的权限。以如下两个方法为例,用户Foo或者Bar可以有权限调用FooOrBar方法,但是没有任何一个用户有权调用CannotCall方法(因为一个用户只一个用户名)。
1: [PrincipalPermission( SecurityAction.Demand, Name="Foo")
2: [PrincipalPermission( SecurityAction.Demand, Name="Bar")]
3: public void FooOrBar()
4: { }
5:
6: [Authorize(Users="Foo")]
7: [Authorize(Users="Bar")]
8: public void CannotCall()
9: {}
三、RequireHttpsAttribute
从名称也可以看出来来,RequireHttpsAttribute这个AuthorizationFilter要求用用户总是以HTTP请求的方式访问目标方法。如果当前并不是一个HTTPS请求(通过当前HttpRequest的IsSecureConnection属性判断),在HTTP方法为GET的情下,会创建一个RedirectResult对象并用其对AuthorizationContext的Result属性进行设置,当前请求的URL地址的Scheme替换成HTTPS就成了该RedirectResult的地址。也就是说,如果当前请求地址为http://www.artech.com/home/index,会自动重定向到https://www.artech.com/home/index。
1: [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited=true, AllowMultiple=false)]
2: public class RequireHttpsAttribute : FilterAttribute, IAuthorizationFilter
3: {
4: protected virtual void HandleNonHttpsRequest(AuthorizationContext filterContext);
5: public virtual void OnAuthorization(AuthorizationContext filterContext);
6: }
如果当前请求的HTTP方法并不是GET,RequireHttpsAttribute会直接抛出一个InvalidOperationException异常。如上面的代码片断所示,针对非HTTPS请求的处理通过调用受保护的方法HandleNonHttpsRequest来完成,如果我们需要不同的处理,可以继承RequireHttpsAttribute并重写该方法。
四、ValidateInputAttribute
为了避免用户在请求中包含一些不合法的内容对网站进行恶意攻击(比如XSS攻击),我们一般需要对请求的输入进行验证。如下面的代码片断所示,表示HTTP请求的基类HttpRequestBase具有一个ValidateInput方法用于验证请求的输入。实际上这个方法仅仅是在请求上作一下标记而已,在读取相应的请求输入时才根据这些表示决定是否需要进行相应的验证。不过为了便于表达,我们就将针对该ValidateInput方法的调用说成是针对请求输入的验证。
1: public abstract class HttpRequestBase
2: {
3: //其他成员
4: public virtual void ValidateInput();
5: }
所有Controller的基类ControllerBase具有如下一个布尔类型的属性ValidateRequest表示是否需要对请求输入进行验证,在默认情况下该属性的默认值为True,意味着针对请求输入的验证默认情况下是开启的。 当ActionInvoker在完成了对所有AuthorizationFilter的执行之后,会根据该属性决定是否会通过调用表示当前请求的HttpRequest对象的ValidateInput方法进行请求输入的验证。
1: public abstract class ControllerBase : IController
2: {
3: //其他成员
4: public bool ValidateRequest { get; set; }
5: }
也正是由于ActionInvoker针对请求输入验证是在完成了所有AuthorizationFilter的执行之后进行的,所以我们可以通过自定义AuthorizationFilter的方式来设置当前Controller的ValidateRequest属性进而开启或者关闭针对请求输入的验证。ValidateInputAttribute就是这么做的,我们可以从如下表示ValidateInputAttribute的定义看出来(构造函数的参数enableValidation表示是否启动针对请求的输入验证)。
1: [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited=true, AllowMultiple=false)]
2: public class ValidateInputAttribute : FilterAttribute, IAuthorizationFilter
3: {
4: public ValidateInputAttribute(bool enableValidation)
5: {
6: this.EnableValidation = enableValidation;
7: }
8:
9: public virtual void OnAuthorization(AuthorizationContext filterContext)
10: {
11: if (filterContext == null)
12: {
13: throw new ArgumentNullException("filterContext");
14: }
15: filterContext.Controller.ValidateRequest = this.EnableValidation;
16: }
17:
18: public bool EnableValidation { get; private set; }
19: }
为了让读者对ValidateInputAttribute这个AuthorizationFilter针对开启和关闭输入验证的作用有一个深刻映像,我们来进行一个简单的实例演示。在通过Visual Studio的ASP.NET MVC项目模板创建的空Web应用中我们 定义了如下一个HomeController,包含在该Controller中的两个Action方法(Action1和Action2)具有一个字符串类型的参数foo,其中Action1上应用了ValidateInputAttribute特性并将参数设置为False。
1: public class HomeController : Controller
2: {
3: [ValidateInput(false)]
4: public void Action1(string foo, string bar)
5: {
6: Response.Write(string.Format("{0}: {1}<br/>", "foo", Server.HtmlEncode(foo)));
7: Response.Write(string.Format("{0}: {1}<br/>", "bar", Server.HtmlEncode(bar)));
8: }
9:
10: public void Action2(string foo, string bar)
11: {
12: Response.Write(string.Format("{0}: {1}<br/>", "foo", Server.HtmlEncode(foo)));
13: Response.Write(string.Format("{0}: {1}<br/>", "bar", Server.HtmlEncode(bar)));
14: }
15: }
我们直接运行该程序并在浏览器中通过输入相应的地址来访问这两个Action,并以查询字符串的形式指定它们的两个参数。为了检验ASP.NET MVC对请求输入的验证,我们将表示参数foo的查询字符串的值设置为为“<script></script>”。如下图所示,Action1能够正常地被调用,而Action2在调用过程中抛出异常 ,并提示请求中包含危险的查询字符串。
在前面文章中我们谈到可以通过AllowHtmlAttribute特性来定义表示Model元数据的ModelMetadata的RequestValidationEnabled属性的设置从而忽略对相应属性数据的验证,使之可以包含具有HTML标签的数据。这与ValidateInputAttribute的作用类似,不同的是AllowHtmlAttribute仅仅针对Model对象的默认属性,而ValidateInputAttribute则是针对整个请求。
五、ValidateAntiForgeryTokenAttribute
具有如下定义的System.Web.Mvc.ValidateAntiForgeryTokenAttribute用于解决一种叫做“跨站请求伪造(CSRF:Cross-Site Request Forgery)”。这是一种不同于XSS(Cross Site Script)的跨站网络攻击,如果说XSS是利用了用户对网站的信任,而CSRF就是利用了站点对认证用户的信任。
1: [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple=false, Inherited=true)]
2: public sealed class ValidateAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
3: {
4: public ValidateAntiForgeryTokenAttribute();
5: public void OnAuthorization(AuthorizationContext filterContext);
6: public string Salt { get; set; }
7: }
我们通过一个简单的例子来对CSRF的原理进行说明。假设我们通过ASP.NET MVC构建了一个博客应用,作为博主的用户可以发表博文,而一般用于可以对博文发表评论。除此之外,注册用于可以修改自己的Email地址,相关的操作定义在如下所示的BlogController的Action方法UpdateAddress中。
1: public class BlogController: Controller
2: {
3: [Authorize]
4: [HttpPost]
5: public void UpdateEmailAddress(string emailAddress)
6: {
7: //Email地址修改操作
8: }
9: //其他成员
10: }
对于上面定义的UpdateEmailAddress方法,由于应用了AuthorizeAttribute特性,意味着只有认证的用户才能调用它来修改自己提供的Email地址。此外,HttpPostAttribute特性应用在该Action方法上,使我们只能以POST请求的方式调用它,这无形之中也增强了安全系数。但是这个方法提供的Email修改功能真的安全吗?它真的确保修改后的Email地址真的是登录用户提供的Email地址吗?
我们假设BlogController所在的Web应用部署的域名为Foo,那么Action方法UpdateEmailAddress对应的地址可以表示为http://foo/blog/updateemailaddress。现在一个恶意攻击者创建如下一个简单的HTML页面,该页面具有一个指向上面这个地址的表单,并且该表单中具有一个名为emailAddress <input>元素提供属于供给者自身的Email地址。由于注册了window的onload事件,该表单会在页面加载完成之后自动提交。
1: <html>
2: <head>
3: <script type="text/javascript">
1:
2: window.onload = function () {
3: document.getElementById("updateEmail").submit();
4: }
5:
</script> 4: </head>
5: <body>
6: <form id="updateEmail" action="http://foo/blog/updateemailaddress"
7: method="post">
8: <input type="hidden" name="emailAddress" value="malicious@gmail.com" />
9: </form>
10: </body>
11: </html>
假设攻击者部署该页面的地址为http://bar/maliciouspage.html。然后它通过某篇博文中添加一个包含如下链接的评论。作为登录用户的你点击该连接后将会间接地调用定义在BlogController的UpdateEmailAddress方法。由于登录用户的安全令牌一般以Cookie形式存在,而该Cookie会存在于发送给针对Action方法UpdateEmailAddress的调用请求中,服务器会认为该请求来自被认证用户,所以最终造成了你的Email地址被恶意修改而不自知。如果攻击者具有你的用户名,它可以通过重置密码,是新的密码发送到属于他自己的电子邮箱中。
1: <img src="http://bar/maliciouspage.html"/>
这个例子充分说明了CSRF是一种比较隐蔽并且具有很大危害型的网络攻击,促成攻击的原因在于服务器在针对某个请求执行某个操作的时候并没有验证请求的真正来源。对于ASP.NET MVC来说,如果我们在执行某个Action方法之前能够确认当前的请求来源的有效性,就能从根本上解决CSRF攻击,而ValidateAntiForgeryTokenAttribute结合HtmlHelper的AntiForgeryToken方法有效地解决了这个问题。
1: public class HtmlHelper
2: {
3: //其他成员
4: public MvcHtmlString AntiForgeryToken();
5: public MvcHtmlString AntiForgeryToken(string salt);
6: public MvcHtmlString AntiForgeryToken(string salt, string domain, string path);
7: }
如上面的代码片断所示,HtmlHelper具有三个AntiForgeryToken方法(这里的方式是HtmlHelper的实例方法,不是扩展方法)。当我们在一个View中调用这些方法是,它们会为我们生成一个所谓“防伪令牌(Anti-Forgery Token)”的字符串,并以此生成一个类型为Hidden的<input>元素。除此之外,该方法的调用还会根据这个防伪令牌设置一个Cookie。接下来我们来详细地来讨论这个过程。
上述的这个防伪令牌通过内部类型为AntiForgeryData的对象生成。如下面的代码片断所示,AntiForgeryData具有四个属性,其核心是通过属性Value表示的值。属性UserName和CreationDate表示访问令牌授权的用户名和创建时间。字符串属性Salt是为了增强防伪令牌的安全系数,不同的Salt值对应着不同的防伪令牌,不同的防伪令牌在不同的地方被使用以避免供给者对一个防伪令牌的破解而使整个应用受到全面的攻击。ValidateAntiForgeryTokenAttribute也具有一个同名的属性。
1: internal sealed class AntiForgeryData
2: {
3: public string Value { get; set; }
4: public string Salt { get; set; }
5: public DateTime CreationDate { get; set; }
6: public string Username { get; set; }
7: }
当AntiForgeryToken被调用的时候,会先根据当前的请求的应用路径(对应HttpRequest的ApplicationPath属性)计算出表示防伪令牌Cookie的名称,该名称会在通过对应用路径进行Base64编码(编码之前需要进行一些特殊字符的替换工作)生成的字符串前添加“__RequestVerificationToken”前缀。
如果当前请求具有一个同名的Cookie,则直接通过对Cookie的值进行反序列化得到一个AntiForgeryData对象。需要注意的是,这里针对AntiForgeryData进行序列化和反序列化并不是一个简单地实现运行时对象到字符串之间的转换,还包含采用MachineKey对AntiForgeryData的四个属性进行加密/解密的过程。如果这样的Cookie不存在,HtmlHelper会随机生成一个长度为16的字节数组,并将对该字节数组进行Base64编码后生成的字符串作为值创建一个AntiForgeryData对象。系统当前时间(UTC)作为该AntiForgeryData对象的创建时间,但是该AntiForgeryData对象的UserName和Salt属性为空。
接下来HtmlHelper会根据之前计算出来的Cookie名称创建一个)HttpCookie对象,而新创建出来的AntiForgeryData对象被序列化后生成的字符串作为该HttpCookie的值。如果我们在AntiForgeryToken方法调用中设置了表示域和路径的domain和path参数,它们将会作为该HttpCookie对象的Path和Domain属性。最后HtmlHelper将HttpCookie对象设置给当前的HTTP响应。
AntiForgeryToken返回的是一个类型为hidden的<input>元素对应的HTML,该Hidden元素的名称为“__RequestVerificationToken”(即代码访问令牌Cookie名称的前缀)。为了生成该Hidden元素的值,HtmlHelper会根据现有的AntiForgeryData对象(从当前请求获取的或者新创建的)创建一个新的AntiForgeryData对象,两个对象具有相同的CreationDate和Value属性,而当前用户名和指定的Salt参数将会设置给新AntiForgeryData对象的UserName和Salt属性。
1: @using (Html.BeginForm())
2: {
3: @Html.AntiForgeryToken("647B8734-EFCA-4F51-9D98-36502D13E4E7")
4: ...
5: }
在一个View中我们通过如上的代码在一个表单中调用HtmlHelper的AntiForgeryToken方法并将一个GUID作为Salt,最终将会生成如下一个名为“__RequestVerificationToken”的Hidden元素。
1: <form action="..." method="post">
2: <input name="__RequestVerificationToken" type="hidden" value="yvLaFQ81JVgguKECyF/oQ+pc2/6q0MuLEaF73PvY7pvxaE68lO5qgXZWhfqIk721CBS0SJZjvOjbc7o7GL3SQ3RxIW90no7FcxzR6ohHUYEKdxyfTBuAVjAuoil5miwoY8+6HNoSPbztyhMVvtCsQDtvQfyW1GNa7qvlQSqYxQW7b6nAR2W0OxNi4NgrFEqbMFrD+4CwwAg4PUWpvcQxYA==" />
3: ...
4: </form>
对于该View的首次访问(或者对应的Cookie不存在),如下所示的名称为“__RequestVerificationToken_L012Y0FwcDEx”防伪令牌Cookie将会设置,并且是HttpOnly的。
1: HTTP/1.1 200 OK
2: Cache-Control: private
3: ...
4: Set-Cookie: __RequestVerificationToken_L012Y0FwcDEx=EYPOofprbB0og8vI+Pzr1unY0Ye5BihYJgoIYBqzvZDZ+hcT5QUu+fj2hvFUVTTCFAZdjgCPzxwIGsoNdEyD8nSUbgapk8Xp3+ZD8cxguUrgl0lAdFd4ZGWEYzz0IN58l5saPJpuaChVR4QaMNbilNG4y7xiN2/UCrBF80LmPO4=; path=/; HttpOnly
5: ...
对于一个请求,如果确保请求提供的表单中具有一个名为“__RequestVerificationToken”的Hidden元素,并且该元素的值与对应的防伪令牌的Cookie值相匹配,就能够确保请求并不是由第三方恶意站点发送的,进而防止CSRF攻击。原因很简单:由于Cookie值是经过加密的,供给者可以得到整个Cookie的内容,但是不能解密获得具体的值(AntiForgeryData的Value属性),所以不可能在提供的表单中也包含一个具有匹配值的Hidden元素。针对防伪令牌的验证就实现在ValidateAntiForgeryTokenAttribute的OnAuthorization方法中。
我们来具体介绍一下实现在ValidateAntiForgeryTokenAttribute中针对防伪令牌的验证逻辑。首先它根据当前请求的应用路径采用与生成防伪令牌Cookie相同的逻辑计算出Cookie名称。如果对应的Cookie不存在于当前请求中,则直接抛出HttpAntiForgeryException异常;否则获取Cookie值,并反序列化生成一个AntiForgeryData对象。
然后从提交的表单中提取一个名称为“__RequestVerificationToken”的输入元素,如果这样的元素不存在,同样抛出HttpAntiForgeryException异常;否则直接对具体的值进行反序列化生成一个AntiForgeryData对象。最后ValidateAntiForgeryTokenAttribute对这两个AntiForgeryData的Value属性进行比较,以及后者的UserName和Salt属性与当前用户名和自身的Salt属性值进行比较,任何一个不匹配都会抛出HttpAntiForgeryException异常。
六、ChildActionOnlyAttribute
如果我们希望定义在Controol中的方法能以子Action的形式在某个View中被调用,这样的调用一般用于生成组成整个View的某个部分的HTML,我们可以在方法上应用ChildActionOnlyAttribute特性。从如下给出的定义可以看出,ChildActionOnlyAttribute实际上是一个AuthorizationFilter,它在重写的OnAuthorization方法中对当前请求进行验证,对于非子Action调用下直接抛出InvalidOperationException异常。
1: [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple=false, Inherited=true)]
2: public sealed class ChildActionOnlyAttribute : FilterAttribute, IAuthorizationFilter
3: {
4: public void OnAuthorization(AuthorizationContext filterContext);
5: }
有的读者可能会问,AuthorizationFilter如何区分当前的请求是基于子Action的调用,而不是一般的Action调用呢?其实很简单,当我们在调用HtmlHelper的扩展方法Action或者RenderAction的时候会将当前的View上下文作为“父View上下文”保存到表示当前路由信息的RouteData的DataTokens属性中,对应的Key为“ParentActionViewContext”。如下面的代码片断所示,ControllerContext中用于判断是否为子Action请求的IsChildAction属性正式通过该路由信息进行判断的。
1: public class ControllerContext
2: {
3: //其他成员
4: public virtual bool IsChildAction
5: {
6: get
7: {
8: RouteData routeData = this.RouteData;
9: if (routeData == null)
10: {
11: return false;
12: }
13: return routeData.DataTokens.ContainsKey("ParentActionViewContext");
14: }
15: }
16: }
相关文章:

ASP.NET MVC的5种AuthorizationFilter
一、IAuthorizationFilter 所有的AuthorizationFilter实现了接口IAuthorizationFilter。如下面的代码片断所示,IAuthorizationFilter定义了一个OnAuthorization方法用于实现授权的操作。作为该方法的参数filterContext是一个表示授权上下文的AuthorizationContext对…...

C语言初学8:函数和作用域
一、函数 函数声明告诉编译器函数的名称、返回值类型和参数。在一个源文件中定义函数且在另一个文件中调用函数时,函数声明是必需的。函数定义提供了函数的实际主体。...

2024年科技盛宴“上海智博会·上海软博会”招商工作接近尾声
2024年上海智博会和上海软博会即将于3月份在上海跨国采购会展中心盛大召开。作为全球科技和软件行业的盛会,这两大展会汇集了业界顶尖的企业、创新技术和前瞻思想,吸引了来自世界各地的专业人士和参展商。 今年的展会将一如既往地为大家呈现最前沿的科技…...

深圳锐科达SIP矿用电话模块SV-2801VP
深圳锐科达SIP矿用电话模块SV-2801VP 一、简介 SV-2800VP系列模块是我司设计研发的一款用于井下的矿用IP音频传输模块,可用此模块打造一套低延迟、高效率、高灵活和多扩展的IP矿用广播对讲系统,亦可对传统煤矿电话系统加装此模块,进行智能化…...

【Qt-数据库】
Qt编程指南 ■ SQLite■ CSV■ JSON ■ SQLite Qt 提供了很多操作数据库的类, SQLite 是非常小的,是轻量级的,完全配置时小于 400KiB,省略可选功能配置时小于 250KiB。 SQLite 是一个进程内的库,实现了自给自足的、无…...

windows文件名命名规范(文件名规范、命名规则、避免特殊字符、注意文件名长度限制260个字符)
文章目录 Windows文件名命名规范1. 基本规则1.1 避免使用特殊字符1.2 限制文件名长度1.3 避免使用预留名称 2. 最佳实践2.1 使用描述性名称2.2 使用连字符或下划线代替空格2.3 使用日期和版本号 3. 实用技巧3.1 批量重命名文件3.2 使用PowerShell进行高级文件操作 Windows文件名…...

如何修改MySQL的默认端口
MySQL是世界上最流行的开源关系型数据库管理系统之一。在某些情况下,由于安全性、网络策略或端口冲突的原因,数据库管理员可能需要更改MySQL服务的默认监听端口。本文将指导您如何在不同的操作系统上更改MySQL的默认端口。 理解MySQL配置文件 MySQL的配…...

Android笔记(二十一):Room组件实现Android应用的持久化处理
一、Room组件概述 Room是Android JetPack架构组件之一,是一个持久处理的库。Room提供了在SQLite数据库上提供抽象层,使之实现数据访问。 (1)实体类(Entity):映射并封装了数据库对应的数据表中…...

uniapp中各种状态的按钮
当涉及状态按钮时,UniApp提供了丰富的选择。UniApp中的状态按钮可以是开关按钮、单选按钮、多选按钮等。开发者可以根据具体需求选择使用合适的状态按钮组件。对于状态按钮,UniApp提供了丰富的API和事件,可以轻松实现状态切换、状态监听等功能…...

模式识别与机器学习-判别式分类器
模式识别与机器学习-判别式分类器 生成式模型和判别式模型的区别线性判别函数多分类情况多分类情况1多分类情况2多分类情况3 例题 广义线性判别函数实例 分段线性判别函数Fisher线性判别感知机算法例:感知机多类别分类 谨以此博客作为学习期间的记录 生成式模型和判…...

c++11 标准模板(STL)(std::pair)(七)访问 pair 的一个元素
定义于头文件 <utility> std::pair 是一个结构体模板,其可于一个单元存储两个相异对象。 pair 是 std::tuple 的拥有两个元素的特殊情况。 访问 pair 的一个元素 std::get(std::pair) template< size_t I, class T1, class T2 > typename std::tuple…...

IP 地址归属地查询
IP 地址归属地查询 1. IP 地址归属地查询2. IP 地址归属地查询References 1. IP 地址归属地查询 https://tool.lu/ip/index.html 2. IP 地址归属地查询 https://www.ip.cn/ip/.html References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/...

实战经验分享:在Java中灵活应用Excel注释和批注
本文由葡萄城技术团队原创并首发。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 前言 注释及批注是 Excel 中比较常用的功能,注释往往针对单元格,起到解释说明的作用&a…...

AUTOSAR从入门到精通-车载以太网(三)
目录 前言 原理 车载以太网总体架构 物理层 数据链路层 以太网帧格式<...

【自然语言处理】用Python从文本中删除个人信息-第二部分
自我介绍 做一个简单介绍,酒架年近48 ,有20多年IT工作经历,目前在一家500强做企业架构.因为工作需要,另外也因为兴趣涉猎比较广,为了自己学习建立了三个博客,分别是【全球IT瞭望】,【…...

设计模式之-中介者模式,快速掌握中介者模式,通俗易懂的讲解中介者模式以及它的使用场景
系列文章目录 设计模式之-6大设计原则简单易懂的理解以及它们的适用场景和代码示列 设计模式之-单列设计模式,5种单例设计模式使用场景以及它们的优缺点 设计模式之-3种常见的工厂模式简单工厂模式、工厂方法模式和抽象工厂模式,每一种模式的概念、使用…...

12.25
led.c #include "led.h" void all_led_init() {RCC_GPIO | (0X3<<4);//时钟使能GPIOE_MODER &(~(0X3<<20));//设置PE10输出GPIOE_MODER | (0X1<<20);//设置PE10为推挽输出GPIOE_OTYPER &(~(0x1<<10));//PE10为低速输出GPIOE_OSPEED…...

MySQL5.7的几种安装方式总结(排错踩坑呕心沥血的经历)
包安装 添加国内源:mysql | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 注意:5.7安装之后有一个临时密码,进行登录并修改新密码后才可以对mysql进行操作。 可以yun list看看各个系统光盘自带的都是什么版本&…...

zookeeper基本使用
目录 环境搭建 单机版搭建 集群版搭建 基本语法使用 可视化客户端 数据结构 节点分类 1. 持久节点 2. 临时节点 3. 有序节点 4. 容器节点 5. TTL节点 节点状态 监听机制 watch监听 永久性watch 应用场景 1. 实现分布式锁 2. 乐观锁更新数据 应用场景总结 选…...

【华为机试】2023年真题B卷(python)-分月饼
一、题目 题目描述: 中秋节公司分月饼,m个员工,买了n个月饼,m<n,每个员工至少分1个月饼,但可以分多个,单人份到最多月饼的个数为Max1,单人分到第二多月饼的个数是Max2,…...

EtherCAT主站SOEM -- 11 -- EtherCAT从站 XML 文件解析
EtherCAT主站SOEM -- 11 -- EtherCAT从站 XML 文件解析 1 EtherCAT 从站信息规范1.1 XML 文件说明1.1.1 XML 数据类型1.1.2 EtherCATInfo1.1.3 Groups1.1.4 Devices1.1.5 Modules1.1.6 Types1.1.6.1 AccessType 的组成1.1.6.2 ArraylnfoType 的组成1.1.6.3 DeviceType 的组成1.…...

YOLOv5算法改进(23)— 更换主干网络GhostNet + 添加CA注意力机制 + 引入GhostConv
前言:Hello大家好,我是小哥谈。本节课就让我们结合论文来对YOLOv5进行组合改进(更换主干网络GhostNet + 添加CA注意力机制 + 引入GhostConv),希望同学们学完本节课可以有所启迪,并且后期可以自行进行YOLOv5算法的改进!🌈 前期回顾: YOLOv5算法改进(1)— 如何去…...

centos系统部署rancher1.6版本并部署服务
1. centos上部署docker. 请参考 博客 2. 用docker安装rancher1.6 sudo docker run -d -v /mnt/rancher/db:/var/lib/mysql --restartunless-stopped -p 8080:8080 rancher/server3.浏览器登录做设置 3.1 浏览器打开 1.117.92.32:8080 #直接就登录了 3.2 第一次进入&am…...

Matlab实时读取串口数据并实时画图方法
** Matlab实时读取串口数据并实时画图方法 ** 按照数据串口协议如:$KT2,1.80,88.18,39.54,42.86,LO[0.72,-1.04,0.35],举例。 s serialport("COM12",115200,"Timeout",5); poszeros(100000,3); j1; data1 read(s,1,"uint8&…...

智能优化算法应用:基于向量加权平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码
智能优化算法应用:基于向量加权平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于向量加权平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.向量加权平均算法4.实验参数设定…...

SpringBoot - Maven 打包合并一个胖 JAR 以及主项目 JAR 依赖 JAR 分离打包解决方案
问题描述 <plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.1.18.RELEASE</version><configuration><!--<classifier>exec</classifier>--…...

react 18 Hooks扩展函数式组件的状态管理
React函数式组件 特点 React函数式组件具有以下特点: 简洁:使用函数的方式定义组件,语法简单直观。无状态:函数式组件没有内部状态(state),只依赖于传入的props。可复用:函数式组…...

智能优化算法应用:基于浣熊算法3D无线传感器网络(WSN)覆盖优化 - 附代码
智能优化算法应用:基于浣熊算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于浣熊算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.浣熊算法4.实验参数设定5.算法结果6.参考文献7.MA…...

c++ qt QtWidgetsApplication 项目 使用外部ui
1 包含生成的UI头文件: 例如,如果你的Qt Designer的.ui文件名为test.ui,那么生成的头文件通常为ui_test.h。 #include "ui_test.h"2 实例化UI类:.h文件中实例化ui 在你的主要类的头文件中,你通常会声明一个U…...

使用React 18、Echarts和MUI实现温度计
关键词 React 18 Echarts和MUI 前言 在本文中,我们将结合使用React 18、Echarts和MUI(Material-UI)库,展示如何实现一个交互性的温度计。我们将使用Echarts绘制温度计的外观,并使用MUI创建一个漂亮的用户界面。 本文…...