Base solution for your next web application
Open Closed

TRY OUT WEB API SERVICE #959


User avatar
0
hasan created

Hello Team,

I am building an Android App for my application on top of ASP.net ZERO

I am authenticating through

api/Account/Authenticate

Now, in My app i want to Send the Token automatically without sending Any Username and Password (for example, i want to have a TRY APP Feature )

How to build one ?

I have tried it but it is not allowing me to do that because it expects the Token in my request

Could you please let me know ?


14 Answer(s)
  • User Avatar
    0
    hikalkan created
    Support Team

    Hi,

    You must send token for your every request after authentication. This is what token based authentication is. So, I could not understood the question actually. If you want to automatically send for every request in your android app, then I don't know. It's out of our scope. I suppose you can find info on the web.

  • User Avatar
    0
    hasan created

    I will put it like this

    I want to create one more method in the controller like

    Account/Authenticate

    How to achieve ?

    Account/Authenticate does not expect Token.

  • User Avatar
    0
    hasan created

    Please reply

    I am waiting for the reply since last week

  • User Avatar
    0
    hikalkan created
    Support Team

    Hi,

    Sorry for the late reply.

    You just create controllers and actions. If you do not put [Authorize] or [AbpApiAuthorize] attributes to your action/controller, it's already not authenticated and can be called by any client without token. If you put these attributes, then it's authenticated. As you see, there is no such attributes in <a class="postlink" href="https://github.com/aspnetzero/aspnet-zero/blob/master/src/MyCompanyName.AbpZeroTemplate.WebApi/WebApi/Controllers/AccountController.cs">https://github.com/aspnetzero/aspnet-ze ... troller.cs</a>

  • User Avatar
    0
    hasan created

    I have tried that and it is not working

    Could you please check it ?

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    Can you share your controller action ?

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    I have tried a simple scenario.

    This is my test controller

    public class TestController : ZeroSupportControllerBase
    {
    	public JsonResult GetTestData()
    	{
    		return Json(new { Name = "ismail", Age = 1 });
    	}
    }
    

    When i make a post request to this action (http://localhost:6240/Test/GetTestData) from postman chrome extension i get the following result.

    {
      "success": true,
      "result": {
        "name": "ismail",
        "age": 1
      },
      "error": null,
      "unAuthorizedRequest": false
    }
    

    It should work the same way with android.

  • User Avatar
    0
    hasan created
    using System;
    using System.Threading.Tasks;
    using System.Web.Http;
    using Abp.Authorization.Users;
    using Abp.UI;
    using Abp.Web.Models;
    using Microsoft.Owin.Infrastructure;
    using Microsoft.Owin.Security;
    using Microsoft.Owin.Security.OAuth;
    using DinePlan.DineConnect.Authorization;
    using DinePlan.DineConnect.Authorization.Roles;
    using DinePlan.DineConnect.Authorization.Users;
    using DinePlan.DineConnect.MultiTenancy;
    using DinePlan.DineConnect.WebApi.Models;
    
    namespace DinePlan.DineConnect.WebApi.Controllers
    {
        public class AccountController : DineConnectApiControllerBase
        {
            public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; }
    
            private readonly UserManager _userManager;
            private readonly AbpLoginResultTypeHelper _abpLoginResultTypeHelper;
    
            static AccountController()
            {
                OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
            }
    
            public AccountController(
                UserManager userManager, 
                AbpLoginResultTypeHelper abpLoginResultTypeHelper)
            {
                _userManager = userManager;
                _abpLoginResultTypeHelper = abpLoginResultTypeHelper;
            }
    
            [HttpPost]
            public async Task<AjaxResponse> Authenticate(LoginModel loginModel)
            {
                CheckModelState();
    
                var loginResult = await GetLoginResultAsync(
                    loginModel.UsernameOrEmailAddress,
                    loginModel.Password,
                    loginModel.TenancyName
                    );
    
                var ticket = new AuthenticationTicket(loginResult.Identity, new AuthenticationProperties());
    
                var currentUtc = new SystemClock().UtcNow;
                ticket.Properties.IssuedUtc = currentUtc;
                ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(30));
    
                return new AjaxResponse(OAuthBearerOptions.AccessTokenFormat.Protect(ticket));
            }
    
    
            private async Task<AbpUserManager<Tenant, Role, User>.AbpLoginResult> GetLoginResultAsync(string usernameOrEmailAddress, string password, string tenancyName)
            {
                var loginResult = await _userManager.LoginAsync(usernameOrEmailAddress, password, tenancyName);
    
                switch (loginResult.Result)
                {
                    case AbpLoginResultType.Success:
                        return loginResult;
                    default:
                        throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(loginResult.Result, usernameOrEmailAddress, tenancyName);
                }
            }
    
            protected virtual void CheckModelState()
            {
                if (!ModelState.IsValid)
                {
                    throw new UserFriendlyException("Invalid request!");
                }
            }
        }
    }
    

    Please execute this and let me know

    Thanks

  • User Avatar
    0
    easyest created

    Hasan, I don't think they can answer Your question, as there is no question about ASP.NET Zero actually. There are only two ways to access a resource - with or without authorization. If You want You resource to be accessible without authorization - remove AbpAuthorize tag from Your method. If You want authorization, You will need to send something from Your Android app for the system to authorize. The method Authenticate gives You a token, that You will need to send with Your requests later and it's up to Your Android application to make sure this token is send with later requests. Another way would be to send basic authenticate header with Your api requests, but I am not sure if ASP.NET Zero supports that. On the other hand, this way is a really bad way, so You should not use it.

  • User Avatar
    0
    hasan created

    I think you did not understand the question I need another method like Authenticate in any Controller which should accept no input and but it has to be give me a Token

    Is it possible in ASP.net ZERO ?

  • User Avatar
    0
    easyest created

    You cannot authorize "nothing". So, there needs to be a user that You can authorize. If You don't want to send user details - no problem with that, just check and authorize the default user. So, You need to have this default user in Your system - just create a tenant "guest" and admin user for this tenant with any password. Then create new method for login without model:

    [HttpPost]
            public async Task<AjaxResponse> Authenticate()
            {
                CheckModelState();
    
                var loginResult = await GetLoginResultAsync(
                    "admin",
                    "adminpassword",
                    "guest"
                    );
    
                var ticket = new AuthenticationTicket(loginResult.Identity, new AuthenticationProperties());
    
                var currentUtc = new SystemClock().UtcNow;
                ticket.Properties.IssuedUtc = currentUtc;
                ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(30));
    
                return new AjaxResponse(OAuthBearerOptions.AccessTokenFormat.Protect(ticket));
            }
    

    The only difference is that You use predefined values for GetLoginResultAsync instead of values from login model.

  • User Avatar
    0
    hikalkan created
    Support Team

    Hi Hasan,

    I also think. we did not understand your problem Why not copy authenticate method or accountcontroller to create a second one, if you want a method exactly like it?

  • User Avatar
    0
    hasan created

    Here is the Code

    using System;
    using System.Threading.Tasks;
    using System.Web.Http;
    using Abp.Authorization.Users;
    using Abp.UI;
    using Abp.Web.Models;
    using Microsoft.Owin.Infrastructure;
    using Microsoft.Owin.Security;
    using Microsoft.Owin.Security.OAuth;
    using DinePlan.DineConnect.Authorization;
    using DinePlan.DineConnect.Authorization.Roles;
    using DinePlan.DineConnect.Authorization.Users;
    using DinePlan.DineConnect.MultiTenancy;
    using DinePlan.DineConnect.WebApi.Models;
    
    namespace DinePlan.DineConnect.WebApi.Controllers
    {
        public class TryController : DineConnectApiControllerBase
        {
            public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; set; }
    
            private readonly UserManager _userManager;
            private readonly AbpLoginResultTypeHelper _abpLoginResultTypeHelper;
    
            static TryController()
            {
                OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
            }
    
            public TryController(
                UserManager userManager, 
                AbpLoginResultTypeHelper abpLoginResultTypeHelper)
            {
                _userManager = userManager;
                _abpLoginResultTypeHelper = abpLoginResultTypeHelper;
            }
    
            
            [HttpPost]
            public async Task<AjaxResponse> Hello()
            {
               
                var loginResult = await GetLoginResultAsync(
                    DEFAULT_USER,
                    DEFAULT_PASSWORD,
                    DEFAULT_TENANCY
                    );
    
                var ticket = new AuthenticationTicket(loginResult.Identity, new AuthenticationProperties());
    
                var currentUtc = new SystemClock().UtcNow;
                ticket.Properties.IssuedUtc = currentUtc;
                ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(30));
    
                return new AjaxResponse(OAuthBearerOptions.AccessTokenFormat.Protect(ticket));
            }
    
            public string DEFAULT_USER => "admin";
    
            public string DEFAULT_PASSWORD => "123qwe";
    
            public string DEFAULT_TENANCY => "Connect";
    
            private async Task<AbpUserManager<Tenant, Role, User>.AbpLoginResult> GetLoginResultAsync(string usernameOrEmailAddress, string password, string tenancyName)
            {
                var loginResult = await _userManager.LoginAsync(usernameOrEmailAddress, password, tenancyName);
    
                switch (loginResult.Result)
                {
                    case AbpLoginResultType.Success:
                        return loginResult;
                    default:
                        throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(loginResult.Result, usernameOrEmailAddress, tenancyName);
                }
            }
    
            protected virtual void CheckModelState()
            {
                if (!ModelState.IsValid)
                {
                    throw new UserFriendlyException("Invalid request!");
                }
            }
        }
    }
    
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi Hasan,

    You need to remove "OAuthBearerOptions" static property from TryController and use "WebApi.Controllers.AccountController.OAuthBearerOptions" in your TryController.