首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我想要同一个数据库上的web (MVC)和API。

我想要同一个数据库上的web (MVC)和API。
EN

Stack Overflow用户
提问于 2017-02-01 16:20:48
回答 1查看 884关注 0票数 0

我有一个数据库,需要用于行政和管理的web接口(事务、计费和其他管理的数量),以及从数据库(产品)“手动”和API向其他较大客户端提供数据(产品)的数据。显然,所有这些都是由SSL和https保护的。

我制作了一个asp.net MVC 5应用程序(业务逻辑和管理),并希望实现API (noob )来向用户提供数据。

不知道如何实现从MVC到API(同一个数据库)的安全性。

这个应用程序很小,我可以重写它。我想试着用核心,但担心我会被困在同一个问题上。

的具体问题:在MVC 5代或.core (MVC 6)中,我应该采取什么方法来使用一个数据库来处理数据、用户和他们的授权?

(推动一切真正的API是我想要避免的事情)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-22 18:56:43

好了,我的项目完成了。我在MVC 5上更进一步。

(我向你们这些完美主义者道歉,但我现在没有时间去除不必要的东西,所以我丢弃了全部文件。)

第一进场-废弃的

首先,我尝试按照推荐的方式设计它:.MVC解决方案、.DB数据库解决方案和.API解决方案。

结论:认证和实体框架存在许多问题。最后我放弃了这种方法

2与成功的

只有一个解决方案.MVC

真正的NuGet安装了.net Api,使用了集成授权扩展,使用了很少的教程(不是单个教程)。注意,我使用ASP.NET标识2.0扩展身份模型并使用整数键代替字符串在ASP.Net MVC应用程序中到处实现HTTPS

以下是修改和加载项:

App_Start -> IdentityConfig.cs

代码语言:javascript
复制
public class ApplicationUserManager : UserManager<ApplicationUser, int>
{
    // *** ADD INT TYPE ARGUMENT TO CONSTRUCTOR CALL:
    public ApplicationUserManager(IUserStore<ApplicationUser, int> store)
        : base(store)
    {
    }

    public static ApplicationUserManager Create(
        IdentityFactoryOptions<ApplicationUserManager> options,
        IOwinContext context)
    {
        // *** PASS CUSTOM APPLICATION USER STORE AS CONSTRUCTOR ARGUMENT:
        var manager = new ApplicationUserManager(
            new ApplicationUserStore(context.Get<ApplicationDbContext>()));

        // Configure validation logic for usernames

        // *** ADD INT TYPE ARGUMENT TO METHOD CALL:
        manager.UserValidator = new UserValidator<ApplicationUser, int>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };

        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = false,
            RequireDigit = true,
            RequireLowercase = true,
            RequireUppercase = true,
        };


            // other code removed for brevity      
        manager.UserLockoutEnabledByDefault = Convert.ToBoolean(ConfigurationManager.AppSettings["UserLockoutEnabledByDefault"].ToString());
        manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(Double.Parse(ConfigurationManager.AppSettings["DefaultAccountLockoutTimeSpan"].ToString()));
        manager.MaxFailedAccessAttemptsBeforeLockout = Convert.ToInt32(ConfigurationManager.AppSettings["MaxFailedAccessAttemptsBeforeLockout"].ToString());


        // Register two factor authentication providers. 
        // This application uses Phone and Emails as a step of receiving a 
        // code for verifying the user You can write your own provider and plug in here.

        // *** ADD INT TYPE ARGUMENT TO METHOD CALL:
        //manager.RegisterTwoFactorProvider("PhoneCode",
        //  new PhoneNumberTokenProvider<ApplicationUser, int>
        //  {
        //      MessageFormat = "Your security code is: {0}"
        //  });

        //// *** ADD INT TYPE ARGUMENT TO METHOD CALL:
        //manager.RegisterTwoFactorProvider("EmailCode",
        //  new EmailTokenProvider<ApplicationUser, int>
        //  {
        //      Subject = "SecurityCode",
        //      BodyFormat = "Your security code is {0}"
        //  });

        //manager.EmailService = new EmailService();
        //manager.SmsService = new SmsService();
        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            // *** ADD INT TYPE ARGUMENT TO METHOD CALL:
            manager.UserTokenProvider =
                new DataProtectorTokenProvider<ApplicationUser, int>(
                    dataProtectionProvider.Create("ASP.NET Identity"));
        }
        return manager;
    }
}


// PASS CUSTOM APPLICATION ROLE AND INT AS TYPE ARGUMENTS TO BASE:
public class ApplicationRoleManager : RoleManager<ApplicationRole, int>
{
    // PASS CUSTOM APPLICATION ROLE AND INT AS TYPE ARGUMENTS TO CONSTRUCTOR:
    public ApplicationRoleManager(IRoleStore<ApplicationRole, int> roleStore)
        : base(roleStore)
    {
    }

    // PASS CUSTOM APPLICATION ROLE AS TYPE ARGUMENT:
    public static ApplicationRoleManager Create(
        IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context)
    {
        return new ApplicationRoleManager(
            new ApplicationRoleStore(context.Get<ApplicationDbContext>()));
    }
}


public class EmailService : IIdentityMessageService
{
    public Task SendAsync(IdentityMessage message)
    {
        // Plug in your email service here to send an email.
        return Task.FromResult(0);
    }
}


public class SmsService : IIdentityMessageService
{
    public Task SendAsync(IdentityMessage message)
    {
        // Plug in your sms service here to send a text message.
        return Task.FromResult(0);
    }
}

//This is useful if you do not want to tear down the database each time you run the application.
//public class ApplicationDbInitializer : DropCreateDatabaseAlways<ApplicationDbContext>
//This example shows you how to create a new database if the Model changes
public class ApplicationDbInitializer : DropCreateDatabaseIfModelChanges<ApplicationDbContext>
{
    protected override void Seed(ApplicationDbContext context)
    {
        //InitializeIdentityForEF(context); //- Do not Seed - IGOR
        //base.Seed(context);
    }

    //Create User=Admin@Admin.com with password=Admin@123456 in the Admin role        
    //public static void InitializeIdentityForEF(ApplicationDbContext db)
    //{
    //  var userManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
    //  var roleManager = HttpContext.Current.GetOwinContext().Get<ApplicationRoleManager>();
    //  const string name = "igor@email.mail";
    //  const string password = "LolLol1";
    //  const string roleName = "lol";

    //  //Create Role Admin if it does not exist
    //  var role = roleManager.FindByName(roleName);
    //  if (role == null)
    //  {
    //      role = new ApplicationRole(roleName);
    //      var roleresult = roleManager.Create(role);
    //  }

    //  var user = userManager.FindByName(name);
    //  if (user == null)
    //  {
    //      user = new ApplicationUser { UserName = name, Email = name };
    //      var result = userManager.Create(user, password);
    //      result = userManager.SetLockoutEnabled(user.Id, false);
    //  }

    //  // Add user admin to Role Admin if not already added
    //  var rolesForUser = userManager.GetRoles(user.Id);
    //  if (!rolesForUser.Contains(role.Name))
    //  {
    //      var result = userManager.AddToRole(user.Id, role.Name);
    //  }
    //}
}


public class ApplicationSignInManager : SignInManager<ApplicationUser, int>
{
    public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) :
        base(userManager, authenticationManager)
    { }

    public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
    {
        return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
    }

    public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
    {
        return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
    }
}

App_Start -> Startup.Auth.cs

代码语言:javascript
复制
public partial class Startup
{
    public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }

    public static string PublicClientId { get; private set; }


    public void ConfigureAuth(IAppBuilder app)
    {
        // Configure the db context, user manager and role manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

        // Enable the application to use a cookie to store information for the signed in user
        // and to use a cookie to temporarily store information about a user logging in with a third party login provider
        // Configure the sign in cookie
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            Provider = new CookieAuthenticationProvider
            {
                // Enables the application to validate the security stamp when the user logs in.
                // This is a security feature which is used when you change a password or add an external login to your account.  
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser, int>(
                    validateInterval: TimeSpan.FromMinutes(2880),
                    regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
                        // Need to add THIS line because we added the third type argument (int) above:
                        getUserIdCallback: (claim) => int.Parse(claim.GetUserId()))
            }
        });
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        // Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
        app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));

        // Enables the application to remember the second login verification factor such as phone or email.
        // Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from.
        // This is similar to the RememberMe option when you log in.
        app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);

        // Uncomment the following lines to enable logging in with third party login providers
        //app.UseMicrosoftAccountAuthentication(
        //    clientId: "",
        //    clientSecret: "");

        //app.UseTwitterAuthentication(
        //   consumerKey: "",
        //   consumerSecret: "");

        //app.UseFacebookAuthentication(
        //   appId: "",
        //   appSecret: "");

        //app.UseGoogleAuthentication(
        //    clientId: "",
        //    clientSecret: "");

        // 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"), //TODO - makni ovo
            AccessTokenExpireTimeSpan = TimeSpan.FromHours(1),
            // In production mode set AllowInsecureHttp = false
            AllowInsecureHttp = true
        };

        // Enable the application to use bearer tokens to authenticate users
        app.UseOAuthBearerTokens(OAuthOptions);
    }
}
//public partial class Startup
//{
//  public void ConfigureAuth(IAppBuilder app)
//  {
//      // Enable the application to use a cookie to store information for the signed in user
//      app.UseCookieAuthentication(new CookieAuthenticationOptions
//      {
//          ExpireTimeSpan = TimeSpan.FromHours(24),
//          CookieSecure = CookieSecureOption.Never,
//          CookieHttpOnly = false,
//          SlidingExpiration = true,
//          AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
//          LoginPath = new PathString("/Account/Login")
//      });
//      // Use a cookie to temporarily store information about a user logging in with a third party login provider
//      app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
//  }
//}

App_Start -> WebApiConfig.cs

代码语言:javascript
复制
public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // TODO: Add any additional configuration code.

        // Web API routes
        config.MapHttpAttributeRoutes();

        //config.Routes.MapHttpRoute(
        //  name: "getkey",
        //  routeTemplate: "api/ApiKeys/Get/{term}"

        //);

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        // WebAPI when dealing with JSON & JavaScript!
        // Setup json serialization to serialize classes to camel (std. Json format)
        var formatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
        formatter.SerializerSettings.ContractResolver =
            new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();

        // make all web-api requests to be sent over https
        config.MessageHandlers.Add(new EnforceHttpsHandler());
    }
}

MySysAdmin控制器,用于角色和初始用户的初始插入和编辑。

代码语言:javascript
复制
public SysAdminController(ApplicationUserManager userManager,
        ApplicationRoleManager roleManager)
    {
        UserManager = userManager;
        RoleManager = roleManager;
    }

    private ApplicationUserManager _userManager;
    public ApplicationUserManager UserManager
    {
        get
        {
            return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
        }
        set
        {
            _userManager = value;
        }
    }

    private ApplicationRoleManager _roleManager;
    public ApplicationRoleManager RoleManager
    {
        get
        {
            return _roleManager ?? HttpContext.GetOwinContext().Get<ApplicationRoleManager>();
        }
        private set
        {
            _roleManager = value;
        }
    }

    public ActionResult RoleIndex()
    {
        return View(RoleManager.Roles);
    }

    public ActionResult RoleCreate()
    {
        return View();
    }

    [HttpPost]
    public async Task<ActionResult> RoleCreate(SysAdminVM.RoleViewModel roleViewModel)
    {
        if (ModelState.IsValid)
        {
            // Use ApplicationRole, not IdentityRole:
            var role = new ApplicationRole(roleViewModel.Name);
            var roleresult = await RoleManager.CreateAsync(role);
            if (!roleresult.Succeeded)
            {
                ModelState.AddModelError("", roleresult.Errors.First());
                return View();
            }
            return RedirectToAction("RoleIndex");
        }
        return View();
    }

    public async Task<ActionResult> RoleEdit(int id)
    {
        if (id > 0)
        {
            var role = await RoleManager.FindByIdAsync(id);
            if (role == null)
            {
                return HttpNotFound();
            }
            SysAdminVM.RoleViewModel roleModel = new SysAdminVM.RoleViewModel { Id = role.Id, Name = role.Name };
            return View(roleModel);
        }
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> RoleEdit([Bind(Include = "Name,Id")] SysAdminVM.RoleViewModel roleModel)
    {
        if (ModelState.IsValid)
        {
            var role = await RoleManager.FindByIdAsync(roleModel.Id);
            role.Name = roleModel.Name;
            await RoleManager.UpdateAsync(role);
            return RedirectToAction("RoleIndex");
        }
        return View();
    }

    [AllowAnonymous]
    public async Task<ActionResult> Initialize()
    {
        if (db.App.Where(x => x.Name.Contains("Initialize")).FirstOrDefault() == null)
        {
            await InitRoleCreate();
            await InitUser();
            db.App.Add(
                new App { Name = "Initialize", Val = "true" }
            );
            db.SaveChanges();
            return View();
        }
        return HttpNotFound();
    }

    private async Task InitRoleCreate()
    {
        var model = new List<string>()
    {
        "SysAdmin",
        "Admin",
        "User",
    };
        foreach (var item in model)
        {
            var role = new ApplicationRole(item);
            await RoleManager.CreateAsync(role);
        }
    }

    private async Task InitUser()
    {
        var user = new ApplicationUser
        {
            UserName = "HerGiz",
            Email = "hergiz@outlook.com",
            Name = "Igor Hermanović",
            Contact = "098 185 3131",
            TwoFactorEnabled = false,
            LockoutEnabled = true,
            EmailConfirmed = true
        };
        var adminResult = await UserManager.CreateAsync(user, "W7xtc2ywfb");
        await UserManager.AddToRolesAsync(user.Id, "SysAdmin");
    }
}

我需要的整个API部分-控制器和开箱即用的登录(在某个地方安装):

代码语言:javascript
复制
[Authorize]
public class ApiKeysController : ApiController
{
    [Authorize]
    [Route("api/getkey/{term}")]
    public ShowFullKeyVM Get(string term)
    {
        if (User.Identity.IsAuthenticated == true)
        {
            if (!string.IsNullOrWhiteSpace(term) && (term.Length == 15 || term.Length == 16))
            {
                var lKey = new LKey();
                var vm = lKey.Search(term);
                if (vm != null)
                {
                    return vm;
                }
            }
            return new ShowFullKeyVM() { Error = "IMEI either is not valid :(", SearchIMEI = term };
        }
        return new ShowFullKeyVM() { Error = "Not Authenticated!!!", SearchIMEI = term };
    }
}

Global.asax

代码语言:javascript
复制
protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        GlobalConfiguration.Configure(WebApiConfig.Register);

        MvcHandler.DisableMvcResponseHeader = true;

        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        App_Start.AutoMapperConfig.DefineMaps();

        ModelBinders.Binders.Add(typeof(decimal), new Extensions.DecimalModelBinder());
        ModelBinders.Binders.Add(typeof(decimal?), new Extensions.DecimalModelBinder());
    }

Web.config

代码语言:javascript
复制
<appSettings>
    <add key="UserLockoutEnabledByDefault" value="true" />
    <add key="DefaultAccountLockoutTimeSpan" value="30" />
    <add key="MaxFailedAccessAttemptsBeforeLockout" value="4" />
 </appSettings>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41984630

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档