新建了个web api项目,运行起来访问api/values的时候提示已拒绝为此请求授权

landon_zeng 2016-07-05 01:25:26
我用vs2015新建了个web api项目,自带了author2.0 权限认证,运行起来访问api/values的时候提示<Message>已拒绝为此请求授权。</Message>,我访问/token路径时又提示{"error":"unsupported_grant_type"},不知道用户密码是什么,请问我如何获取token?



跪求大神指点啊!!
...全文
6131 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
alook_6 2016-08-25
  • 打赏
  • 举报
回复
引用 18 楼 zhaoyaoxing 的回复:
不会有人这样构造实现的:http://xxxxxxx?token=issued_token 将token曝露在url中不安全而且代码实现时也很丑

GET http://10.10.134.63:9002/api/Account/UserInfo HTTP/1.1
Host: 10.10.134.63:9002
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0
Accept: */*
Authorization: Bearer u3kZgQLUbMn2wX0JPF4Os75qi2XugVcNUR5k_p
Authorization: Bearer YOUR_ACCESS_TOKEN 官方文档:http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api
token怎么传的?
alook_6 2016-08-25
  • 打赏
  • 举报
回复
token怎么传的啊?
Yunnying 2016-07-13
  • 打赏
  • 举报
回复
引用 19 楼 zhanglong_longlong 的回复:
把这个特性注释了就行了[Authorize]
可以是可以。但是生产环境里,总不能所有的api都不使用用户验证吧
【Help】 2016-07-13
  • 打赏
  • 举报
回复
把这个特性注释了就行了[Authorize]
Yunnying 2016-07-13
  • 打赏
  • 举报
回复
不会有人这样构造实现的:http://xxxxxxx?token=issued_token 将token曝露在url中不安全而且代码实现时也很丑

GET http://10.10.134.63:9002/api/Account/UserInfo HTTP/1.1
Host: 10.10.134.63:9002
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0
Accept: */*
Authorization: Bearer u3kZgQLUbMn2wX0JPF4Os75qi2XugVcNUR5k_p
Authorization: Bearer YOUR_ACCESS_TOKEN 官方文档:http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api
Yunnying 2016-07-12
  • 打赏
  • 举报
回复
引用 15 楼 ly496524246 的回复:
[quote=引用 14 楼 zhaoyaoxing 的回复:] 是。 理论上来说,跟vs2015建出来的不会有太大差别
恩恩,非常感谢,获取到token了!! 还有一个问题就是我整个项目里搜索了一下token,也没找到token这个控制器?请问这个在什么地方?还有获取token的方法也没看到[/quote] 正如我贴的代码的第一部分,token不过是个路径,它被map到了一个实现里,map的时候指明了实现是由ApplicationOAuthProvider负责的。 正如贴的第二段代码,是ApplicationOAuthProvider基于其父类做的实现。说明了其实现的具体内容。尤其是GrantResourceOwnerCredentials这个方法。是验证机制和token的颁发。 它的示例代码里,只有用户名和密码的验证,你一样可以改造方法,添加上手机号和短信验证码的方式等等。 当然了,这只是示例。production env中还有很多需要考虑的问题,比如token的维持和refresh,多台web server时相互之间的token认证共享什么的。 话说,小朋友你在哪个城市的?你的这种求知精神难能可贵,让人欣赏啊
landon_zeng 2016-07-12
  • 打赏
  • 举报
回复
引用 14 楼 zhaoyaoxing 的回复:
是。 理论上来说,跟vs2015建出来的不会有太大差别
恩恩,非常感谢,获取到token了!! 还有一个问题就是我整个项目里搜索了一下token,也没找到token这个控制器?请问这个在什么地方?还有获取token的方法也没看到
Yunnying 2016-07-12
  • 打赏
  • 举报
回复
是。 理论上来说,跟vs2015建出来的不会有太大差别
landon_zeng 2016-07-12
  • 打赏
  • 举报
回复
引用 12 楼 zhaoyaoxing 的回复:
具体的返回值你可以看一下response。里面有token,再访问values的时候带上。
好的,我试试,话说vs2013新建web api的时候也自带了oAuth2.0认证了吗?
Yunnying 2016-07-12
  • 打赏
  • 举报
回复
引用 11 楼 ly496524246 的回复:
[quote=引用 10 楼 zhaoyaoxing 的回复:] 先调用register创建一个用户 然后用此用户名和密码post到/token
好的,我试试看,需要传哪些参数呢?我整个项目里搜索了一下token,也没找到token这个控制器?请问这个在什么地方?还有获取token的方法也没看到[/quote] 我以vs2013里的mvc api 2.0举例,其声明与引用之处: 1. $\App_Start\Startup.Auth.cs

            // Configure the application for OAuth based flow
            PublicClientId = "self";
            OAuthOptions = new OAuthAuthorizationServerOptions
            {
                TokenEndpointPath = new PathString("/Token"),
                Provider = new ApplicationOAuthProvider(PublicClientId),
                AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
                AllowInsecureHttp = true
            };

            // Enable the application to use bearer tokens to authenticate users
            app.UseOAuthBearerTokens(OAuthOptions);
2, $\Providers\ApplicationOAuthProvider.cs

        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();

            ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);

            if (user == null)
            {
                context.SetError("invalid_grant", "The user name or password is incorrect.");
                return;
            }

            ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
               OAuthDefaults.AuthenticationType);
            ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
                CookieAuthenticationDefaults.AuthenticationType);

            AuthenticationProperties properties = CreateProperties(user.UserName);
            AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
            context.Validated(ticket);
            context.Request.Context.Authentication.SignIn(cookiesIdentity);

        }
3. register api: POST api/Account/Register

{
  "Email": "sample string 1",
  "Password": "sample string 2",
  "ConfirmPassword": "sample string 3"
}
4. post /token POST /Token Content-Type: application/x-www-form-urlencoded body: grant_type=password&username=uname&password=pwd 具体的返回值你可以看一下response。里面有token,再访问values的时候带上。
landon_zeng 2016-07-12
  • 打赏
  • 举报
回复
引用 10 楼 zhaoyaoxing 的回复:
先调用register创建一个用户 然后用此用户名和密码post到/token
好的,我试试看,需要传哪些参数呢?我整个项目里搜索了一下token,也没找到token这个控制器?请问这个在什么地方?还有获取token的方法也没看到
Yunnying 2016-07-12
  • 打赏
  • 举报
回复
引用 9 楼 ly496524246 的回复:
[quote=引用 7 楼 ymq_2012 的回复:] 你要是用vs自检的 他用的ef生成的sql,你修改一下连接数据库的配置,然后生成一下,你也可以不用他们的登录方法,自己写登录方法
ef生成的数据库里没有数据,我看了一下,是不是要添加用户账户密码才能获取到token?添加到哪张表呢?[/quote] 先调用register创建一个用户 然后用此用户名和密码post到/token
landon_zeng 2016-07-12
  • 打赏
  • 举报
回复
引用 7 楼 ymq_2012 的回复:
你要是用vs自检的 他用的ef生成的sql,你修改一下连接数据库的配置,然后生成一下,你也可以不用他们的登录方法,自己写登录方法
ef生成的数据库里没有数据,我看了一下,是不是要添加用户账户密码才能获取到token?添加到哪张表呢?
landon_zeng 2016-07-12
  • 打赏
  • 举报
回复
ef生成的数据库里没有数据,我看了一下,是不是要添加用户账户密码才能获取到token?添加到哪张表呢?
landon_zeng 2016-07-12
  • 打赏
  • 举报
回复
引用 16 楼 zhaoyaoxing 的回复:
正如我贴的代码的第一部分,token不过是个路径,它被map到了一个实现里,map的时候指明了实现是由ApplicationOAuthProvider负责的。 正如贴的第二段代码,是ApplicationOAuthProvider基于其父类做的实现。说明了其实现的具体内容。尤其是GrantResourceOwnerCredentials这个方法。是验证机制和token的颁发。 它的示例代码里,只有用户名和密码的验证,你一样可以改造方法,添加上手机号和短信验证码的方式等等。 当然了,这只是示例。production env中还有很多需要考虑的问题,比如token的维持和refresh,多台web server时相互之间的token认证共享什么的。 话说,小朋友你在哪个城市的?你的这种求知精神难能可贵,让人欣赏啊
非常感谢您详细的解释,麻烦您了,我在上海这边,最近想自己做个项目出来,需要用到web api,之前自己也做过类似的oAuth2.0认证方式,然后最近不是新出了core吗,然后我下了vs2015想看看,建了个web api,发现他自带了oAuth2.0认证,而且比我之前写的那个认证方式更成熟,我之前做的获取token的时候是根据用户名和密码生成固定的token,而vs2015自带的这个好像是每次请求得到token都不一样,所以想探知清楚,知道自己的缺点在什么地方! 还有最后一个问题,就是我用ajax请求得到了access_token

{"access_token":"u3kZgQLUbMn2wX0JPF4Os75qi2XugVcNUR5k_pB95sx4WEGvPlsr1t6TLxgmJYna9KGU1hY1AFUvImALMu8dn_ZhB38-ylJMkcjGeR6Z6W0drrP434ey3terVoQfCGo7af5BVQCKX-6Q6dTSNeGEqn7PPfzcUhV1MRN9z3mb_epg3EI3HUTUP1MfvQPNUU_CtdGpOlMKFCHYRvCJwV_l-3cUJrIQnlctQQC895LDWHLtTawkfmOvHf3B1NI7I6Wg8s3R8Yanf6bmLRw4-oeezTnaWDlKsF5kwNIGwI-kfcsJ7bK6BHMNqMfL8EFznYFcmhfbUyiL1fS6xMEQ0BxCzkewPDSvNYZtkE_eiCyjrJIwKmAyG4TBW5gWJEEG6HLro_6nDSWTFWpVQc9VzMspXObsdsXI2y3onLr2lR6UnOpDEs6wQQ-JmHfTZdoeW73iWoyL7gtOMoLyAXAfSmCCYykzwSAOifmcTVYT6iLOY3I","token_type":"bearer","expires_in":1209599,"userName":"810156785@qq.com",".issued":"Tue, 12 Jul 2016 05:36:00 GMT",".expires":"Tue, 26 Jul 2016 05:36:00 GMT"}
然后复制token的值到http://10.10.134.63:9002/api/Account/UserInfo?token=获取到的access_token url中,其中api/Account/UserInfo是get方式的,按理说我得到token后再每个api后面加上我的token 就是有权访问该接口了,但是按照上面说的去访问我的接口的时候还是提示“已拒绝为此请求授权”!
  • 打赏
  • 举报
回复
引用 5 楼 ly496524246 的回复:
[quote=引用 2 楼 ymq_2012 的回复:]

private string GetToken(string host)
        {
            var client = new RestClient(host);
            var request = new RestRequest("/token", Method.POST);
            request.AddParameter("grant_type", "password");
            request.AddParameter("userName", "用户名");
            request.AddParameter("password", "密码");
            //request.AddHeader("Authorization", Convert.ToBase64String(Encoding.ASCII.GetBytes(clientId + ":" + clientSecret)));
            var response = client.Execute(request);
            var s = JObject.Parse(response.Content)["access_token"].Value<string>();
            return s;
        }
这方法里的用户名和密码是什么?vs2015自带的认证方式里没看到查询数据库诶,还有就是他自己生成的代码里有GrantResourceOwnerCredentials这个方法,代码如下图这个代码有问题吗?[/quote] 你要是用vs自检的 他用的ef生成的sql,你修改一下连接数据库的配置,然后生成一下,你也可以不用他们的登录方法,自己写登录方法
landon_zeng 2016-07-10
  • 打赏
  • 举报
回复
引用 2 楼 ymq_2012 的回复:
这个是因为你没有登录的原因,下面是我写的一个获取token的方法,你看看

private string GetToken(string host)
        {
            var client = new RestClient(host);
            var request = new RestRequest("/token", Method.POST);
            request.AddParameter("grant_type", "password");
            request.AddParameter("userName", "用户名");
            request.AddParameter("password", "密码");
            //request.AddHeader("Authorization", Convert.ToBase64String(Encoding.ASCII.GetBytes(clientId + ":" + clientSecret)));
            var response = client.Execute(request);
            var s = JObject.Parse(response.Content)["access_token"].Value<string>();
            return s;
        }
你写的webapi 下这个项目有个ApplicationOAuthProvider 类,你可以在这里实现自己的登录方式

/// 用户名密码的认证
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            bool loginSuccess = true;
            int userId = 0;
            //令牌中间件提供者允许CORS
            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
            //验证用户名和密码
            var userName = context.UserName;
            var password = context.Password;
            ManagerUser user = new ManagerUserCollection().Where(ManagerUser.Columns.UserName, userName).Where(ManagerUser.Columns.Password, password).Where(ManagerUser.Columns.DeleteMark, 0).Load().FirstOrDefault();
            if (user != null && user.Id > 0)
            {
              //登录成功的处理
                loginSuccess = true;
            }
            else
                loginSuccess = false;
            if (loginSuccess)
            {
                var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
                oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
                oAuthIdentity.AddClaim(new Claim(ClaimTypes.UserData, userId.ToString()));
                var authenticationProperties = new AuthenticationProperties();
                var ticket = new AuthenticationTicket(oAuthIdentity, authenticationProperties);
                context.Validated(ticket);
            }
            else
            {
                context.SetError("invalid_grant", "用户名或密码不正确。");
                return;
            }
            base.GrantResourceOwnerCredentials(context);
        }
好的,我试试看
landon_zeng 2016-07-10
  • 打赏
  • 举报
回复
难道vs2015新建的web api自带的author 认证是不完善的?不能直接拿来用吗?
landon_zeng 2016-07-10
  • 打赏
  • 举报
回复
引用 2 楼 ymq_2012 的回复:

private string GetToken(string host)
{
var client = new RestClient(host);
var request = new RestRequest("/token", Method.POST);
request.AddParameter("grant_type", "password");
request.AddParameter("userName", "用户名");
request.AddParameter("password", "密码");
//request.AddHeader("Authorization", Convert.ToBase64String(Encoding.ASCII.GetBytes(clientId + ":" + clientSecret)));
var response = client.Execute(request);
var s = JObject.Parse(response.Content)["access_token"].Value<string>();
return s;
}

这方法里的用户名和密码是什么?vs2015自带的认证方式里没看到查询数据库诶,还有就是他自己生成的代码里有GrantResourceOwnerCredentials这个方法,代码如下图这个代码有问题吗?
myhope88 2016-07-08
  • 打赏
  • 举报
回复
需要登录才能调用的吧
加载更多回复(2)

62,266

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧