Secure Code Warrior_.Net Core 資安練習_LDAP注入

 





有害程式

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MusicStore.Extensions;
using MusicStore.Models;
using MusicStore.Models.ViewModels.Account;
using MusicStore.Options;
using MusicStore.Repositories.Contracts;
using MusicStore.Services.Contracts;
using System;
using System.DirectoryServices.Protocols;
using System.Linq;
using System.Threading.Tasks;
using SearchScope = System.DirectoryServices.Protocols.SearchScope;

namespace MusicStore.Controllers
{
    [AutoValidateAntiforgeryToken]
    [AllowAnonymous]
    public class AccountController : Controller
    {
        private UserManager<User> userManager;
        private SignInManager<User> signInManager;
        private IRecaptchaService recaptchaService;
        private LDAPOptions LDAPOptions;
        private IListenerRepository listenerRepository;
        private IMusicianRepository musicianRepository;
        private IEmailService emailService;
        private ILogger<AccountController> logger;

        public AccountController(UserManager<User> userManager,
            SignInManager<User> signInManager,
            IRecaptchaService recaptchaService,
            IOptions<AppOptions> optionsAccessor,
            IListenerRepository listenerRepository,
            IMusicianRepository musicianRepository,
            IEmailService emailService,
            ILogger<AccountController> logger)
        {
            this.userManager = userManager;
            this.signInManager = signInManager;
            this.recaptchaService = recaptchaService;
            this.listenerRepository = listenerRepository;
            this.musicianRepository = musicianRepository;
            this.emailService = emailService;
            LDAPOptions = optionsAccessor.Value.LDAPOptions;
            this.logger = logger;
        }

        [HttpGet]
        public async Task<IActionResult> Login()
        {
            if (User.Identity.IsAuthenticated)
            {
                var role = (await userManager
                    .GetRolesAsync(await userManager.GetUserAsync(User)))
                    .SingleOrDefault();
                switch (role)
                {
                    case "Musician":
                        return RedirectToAction("Index", "Musician");
                    case "Admin":
                        return RedirectToAction("Index", "Admin");
                    case "Listener":
                        return RedirectToAction("Index", "Listener");
                    default:
                        await signInManager.SignOutAsync();
                        break;
                }
            }
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> Login(LoginViewModel model)
        {
            if (ModelState.IsValid)
            {
                var captchaResponse =
                    await recaptchaService.Validate(Request.Form);
                if (!captchaResponse.Success)
                {
                    logger.LogInformation($"reCaptcha error with login " +
                        $"{model.Login}");
                    ModelState.AddModelError("reCaptchaError",
                        "reCAPTCHA error occured. Please try again.");
                    return View(model);
                }
                var result =
                    await signInManager.PasswordSignInAsync(model.Login,
                    model.Password, model.RememberMe, true);
                if (result.Succeeded)
                {
                    return RedirectToAction("Login");
                }
            }
            logger.LogInformation($"Failed authentication for login" +
                $"{model.Login}");
            ModelState.AddModelError("", $"Wrong login {model.Login} and/or password");
            return View(model);
        }

        [HttpPost]
        public async Task<IActionResult> LoginLDAP(LoginViewModel model)
        {
            string ldapPath = $"ou=People,dc=music-store,dc=com";
            string ldapDomain = LDAPOptions.LdapHost;
            var connection = new LdapConnection(ldapDomain);
            try
            {
                var captchaResponse =
                       await recaptchaService.Validate(Request.Form);
                if (!captchaResponse.Success)
                {
                    logger.LogInformation($"reCaptcha error with login " +
                        $"{model.Login}");
                    ModelState.AddModelError("reCaptchaError",
                        "reCAPTCHA error occured. Please try again.");
                    return View(model);
                }
                var filter =
                    $"(&(uid={model.Login})" +
                    $"(objectClass=musicStoreUser))";
                var request = new SearchRequest(ldapPath, filter,
                    SearchScope.Subtree);
                var response = connection.SendRequest(request)
                    as SearchResponse;
                if (response.Entries.Count > 0)
                {
                    if (userManager.PasswordHasher.VerifyHashedPassword(null,
                        response.Entries[0].Attributes["userPassword"]
                        .GetValues(typeof(string)).FirstOrDefault() as string,
                        model.Password) == PasswordVerificationResult.Success)
                    {
                        var result =
                            await signInManager.PasswordSignInAsync(model.Login,
                            model.Password, model.RememberMe, true);
                        if (result.Succeeded)
                        {
                            return RedirectToAction("Login");
                        }
                    }
                }
            }
            catch (LdapException ex)
            {
                logger.LogError($"LDAP connection error for user" +
                    $"{model.Login}. Info: {ex.Message}, " +
                    $"StackTrace: {ex.StackTrace}");
                ModelState.AddModelError("", "Wrong login and/or password");
            }
            catch (Exception ex)
            {
                logger.LogError($"Unknown error: Info: {ex.Message}, " +
                    $"StackTrace: {ex.StackTrace}");
                throw;
            }
            return View("Login", model);
        }

        [HttpGet]
        public IActionResult Register()
        {
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> Register(RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {
                var captchaResponse =
                    await recaptchaService.Validate(Request.Form);
                if (!captchaResponse.Success)
                {
                    logger.LogInformation($"reCaptcha register fail. Login " +
                        $"{model.Login}");
                    ModelState.AddModelError("reCaptchaError",
                        "reCAPTCHA error occured. Please try again.");
                    return View(model);
                }
                var user = new User
                {
                    UserName = model.Login,
                    Email = model.Email,
                    Name = model.Name
                };
                try
                {
                    var result = await userManager.CreateAsync(user,
                        model.Password);
                    if (result.Succeeded)
                    {
                        await userManager.AddToRoleAsync(user,
                            model.Role.GetDescription());
                        switch (model.Role)
                        {
                            case Role.Listener:
                                await listenerRepository.Create(new Listener
                                {
                                    User = user
                                });
                                break;
                            case Role.Musician:
                                await musicianRepository.Create(new Musician
                                {
                                    User = user
                                });
                                break;
                        }
                        var code = await userManager
                            .GenerateEmailConfirmationTokenAsync(user);
                        var callbackUrl = Url.Action(
                            "ConfirmEmail",
                            "Account",
                            new { userId = user.Id, code = code },
                            protocol: HttpContext.Request.Scheme);
                        await emailService.SendEmailAsync(model.Email,
                            "Confirm your account", $"Confirm account by " +
                            $"following the link: " +
                            $"<a href='{callbackUrl}'>link</a>");

                        return Content("To end registration please follow " +
                            "the instructions which have been sent to your " +
                            "email.");
                    }
                    else
                    {
                        foreach (var error in result.Errors)
                        {
                            ModelState.AddModelError("", error.Description);
                        }
                    }
                }
                catch (Exception ex)
                {
                    logger.LogError($"Error while register user. " +
                        $"Info: {ex.Message} StackTrace: {ex.StackTrace}");
                    ModelState.AddModelError("", "Unknown error has ocurred, " +
                        "please try again or contact administrator.");
                }
            }
            return View(model);
        }

        [HttpGet]
        public async Task<IActionResult> ConfirmEmail(string userId, 
            string code)
        {
            if (userId == null || code == null)
            {
                return RedirectToAction("Login");
            }
            var user = await userManager.FindByIdAsync(userId);
            if (user == null)
            {
                return RedirectToAction("Login");
            }
            var result = await userManager.ConfirmEmailAsync(user, code);
            return RedirectToAction("Login");
        }

        [HttpGet]
        public IActionResult ForgotPassword()
        {
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> ForgotPassword(
            ForgotPasswordViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = await userManager.FindByEmailAsync(model.Email);
                if (user == null ||
                    !(await userManager.IsEmailConfirmedAsync(user)))
                {
                    return Content("Instructions for changing password have " +
                        "been sent on your email");
                }

                var code = await userManager
                    .GeneratePasswordResetTokenAsync(user);
                var callbackUrl = Url.Action("ResetPassword", "Account",
                    new { userId = user.Id, code = code },
                    protocol: HttpContext.Request.Scheme);
                await emailService.SendEmailAsync(model.Email, "Reset Password",
                $"To change password follow the link: " +
                $"<a href='{callbackUrl}'>link</a>");
                return Content("Instructions for changing your password have " +
                    "been sent to your email.");
            }
            return View(model);
        }

        [HttpGet]
        public IActionResult ResetPassword(string code = null)
        {
            return code == null ? View("Login") : View(
                new ResetPasswordViewModel
                {
                    Code = code
                });
        }

        [HttpPost]
        public async Task<IActionResult> ResetPassword(
            ResetPasswordViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }
            var user = await userManager.FindByEmailAsync(model.Email);
            if (user == null)
            {
                return View("ResetPasswordConfirmation");
            }
            var result = await userManager.ResetPasswordAsync(user,
                model.Code, model.Password);
            if (result.Succeeded)
            {
                return View("ResetPasswordConfirmation");
            }
            foreach (var error in result.Errors)
            {
                ModelState.AddModelError(string.Empty, error.Description);
            }
            return View(model);
        }

        [HttpGet]
        [Authorize]
        public IActionResult ChangePassword()
        {
            return View();
        }

        [HttpPost]
        [Authorize]
        public async Task<IActionResult> ChangePassword(
            ChangePasswordViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = await userManager.FindByIdAsync(userManager
                    .GetUserId(User));
                var result = await userManager.ChangePasswordAsync(user,
                    model.OldPassword, model.Password);
                if (result.Succeeded)
                    return RedirectToAction("Login");
                else
                {
                    foreach (var error in result.Errors)
                        ModelState.AddModelError("", error.Description);
                }
            }
            return View(model);
        }


        [HttpGet]
        [Authorize]
        public async Task<IActionResult> LogOut()
        {
            await signInManager.SignOutAsync();
            return RedirectToAction(nameof(Login));
        }

        [HttpGet]
        [Authorize]
        public async Task<IActionResult> UserInfo()
        {
            var user = await userManager.GetUserAsync(User);
            if (user == null)
                return NotFound();
            var model = new UserInfoViewModel 
            {
                Email = user.Email,
                UserName = user.UserName
            };
            return View(model);
        }
    }
}



解決程式方案

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MusicStore.Extensions;
using MusicStore.Models;
using MusicStore.Models.ViewModels.Account;
using MusicStore.Options;
using MusicStore.Repositories.Contracts;
using MusicStore.Services.Contracts;
using System;
using System.DirectoryServices.Protocols;
using System.Linq;
using System.Threading.Tasks;
using SearchScope = System.DirectoryServices.Protocols.SearchScope;

namespace MusicStore.Controllers
{
    [AutoValidateAntiforgeryToken]
    [AllowAnonymous]
    public class AccountController : Controller
    {
        private UserManager<User> userManager;
        private SignInManager<User> signInManager;
        private IRecaptchaService recaptchaService;
        private LDAPOptions LDAPOptions;
        private IListenerRepository listenerRepository;
        private IMusicianRepository musicianRepository;
        private IEmailService emailService;
        private ILogger<AccountController> logger;

        public AccountController(UserManager<User> userManager,
            SignInManager<User> signInManager,
            IRecaptchaService recaptchaService,
            IOptions<AppOptions> optionsAccessor,
            IListenerRepository listenerRepository,
            IMusicianRepository musicianRepository,
            IEmailService emailService,
            ILogger<AccountController> logger)
        {
            this.userManager = userManager;
            this.signInManager = signInManager;
            this.recaptchaService = recaptchaService;
            this.listenerRepository = listenerRepository;
            this.musicianRepository = musicianRepository;
            this.emailService = emailService;
            LDAPOptions = optionsAccessor.Value.LDAPOptions;
            this.logger = logger;
        }

        [HttpGet]
        public async Task<IActionResult> Login()
        {
            if (User.Identity.IsAuthenticated)
            {
                var role = (await userManager
                    .GetRolesAsync(await userManager.GetUserAsync(User)))
                    .SingleOrDefault();
                switch (role)
                {
                    case "Musician":
                        return RedirectToAction("Index", "Musician");
                    case "Admin":
                        return RedirectToAction("Index", "Admin");
                    case "Listener":
                        return RedirectToAction("Index", "Listener");
                    default:
                        await signInManager.SignOutAsync();
                        break;
                }
            }
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> Login(LoginViewModel model)
        {
            if (ModelState.IsValid)
            {
                var captchaResponse =
                    await recaptchaService.Validate(Request.Form);
                if (!captchaResponse.Success)
                {
                    logger.LogInformation($"reCaptcha error with login " +
                        $"{model.Login}");
                    ModelState.AddModelError("reCaptchaError",
                        "reCAPTCHA error occured. Please try again.");
                    return View(model);
                }
                var result =
                    await signInManager.PasswordSignInAsync(model.Login,
                    model.Password, model.RememberMe, true);
                if (result.Succeeded)
                {
                    return RedirectToAction("Login");
                }
            }
            logger.LogInformation($"Failed authentication for login" +
                $"{model.Login}");
            ModelState.AddModelError("", $"Wrong login {model.Login} and/or password");
            return View(model);
        }

        [HttpPost]
        public async Task<IActionResult> LoginLDAP(LoginViewModel model)
        {
            string ldapPath = $"ou=People,dc=music-store,dc=com";
            string ldapDomain = LDAPOptions.LdapHost;
            var connection = new LdapConnection(ldapDomain);
            try
            {
                var captchaResponse =
                       await recaptchaService.Validate(Request.Form);
                if (!captchaResponse.Success)
                {
                    logger.LogInformation($"reCaptcha error with login " +
                        $"{model.Login}");
                    ModelState.AddModelError("reCaptchaError",
                        "reCAPTCHA error occured. Please try again.");
                    return View(model);
                }
                var filter =
                    "(&(uid=" +
                    Microsoft.Security.Application.Encoder
                        .LdapFilterEncode(model.Login) +
                     ")(objectClass=musicStoreUser))";
                var request = new SearchRequest(ldapPath, filter,
                    SearchScope.Subtree);
                var response = connection.SendRequest(request)
                    as SearchResponse;
                if (response.Entries.Count > 0)
                {
                    if (userManager.PasswordHasher.VerifyHashedPassword(null,
                        response.Entries[0].Attributes["userPassword"]
                        .GetValues(typeof(string)).FirstOrDefault() as string,
                        model.Password) == PasswordVerificationResult.Success)
                    {
                        var result =
                            await signInManager.PasswordSignInAsync(model.Login,
                            model.Password, model.RememberMe, true);
                        if (result.Succeeded)
                        {
                            return RedirectToAction("Login");
                        }
                    }
                }
            }
            catch (LdapException ex)
            {
                logger.LogError($"LDAP connection error for user" +
                    $"{model.Login}. Info: {ex.Message}, " +
                    $"StackTrace: {ex.StackTrace}");
                ModelState.AddModelError("", "Wrong login and/or password");
            }
            catch (Exception ex)
            {
                logger.LogError($"Unknown error: Info: {ex.Message}, " +
                    $"StackTrace: {ex.StackTrace}");
                throw;
            }
            return View("Login", model);
        }

        [HttpGet]
        public IActionResult Register()
        {
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> Register(RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {
                var captchaResponse =
                    await recaptchaService.Validate(Request.Form);
                if (!captchaResponse.Success)
                {
                    logger.LogInformation($"reCaptcha register fail. Login " +
                        $"{model.Login}");
                    ModelState.AddModelError("reCaptchaError",
                        "reCAPTCHA error occured. Please try again.");
                    return View(model);
                }
                var user = new User
                {
                    UserName = model.Login,
                    Email = model.Email,
                    Name = model.Name
                };
                try
                {
                    var result = await userManager.CreateAsync(user,
                        model.Password);
                    if (result.Succeeded)
                    {
                        await userManager.AddToRoleAsync(user,
                            model.Role.GetDescription());
                        switch (model.Role)
                        {
                            case Role.Listener:
                                await listenerRepository.Create(new Listener
                                {
                                    User = user
                                });
                                break;
                            case Role.Musician:
                                await musicianRepository.Create(new Musician
                                {
                                    User = user
                                });
                                break;
                        }
                        var code = await userManager
                            .GenerateEmailConfirmationTokenAsync(user);
                        var callbackUrl = Url.Action(
                            "ConfirmEmail",
                            "Account",
                            new { userId = user.Id, code = code },
                            protocol: HttpContext.Request.Scheme);
                        await emailService.SendEmailAsync(model.Email,
                            "Confirm your account", $"Confirm account by " +
                            $"following the link: " +
                            $"<a href='{callbackUrl}'>link</a>");

                        return Content("To end registration please follow " +
                            "the instructions which have been sent to your " +
                            "email.");
                    }
                    else
                    {
                        foreach (var error in result.Errors)
                        {
                            ModelState.AddModelError("", error.Description);
                        }
                    }
                }
                catch (Exception ex)
                {
                    logger.LogError($"Error while register user. " +
                        $"Info: {ex.Message} StackTrace: {ex.StackTrace}");
                    ModelState.AddModelError("", "Unknown error has ocurred, " +
                        "please try again or contact administrator.");
                }
            }
            return View(model);
        }

        [HttpGet]
        public async Task<IActionResult> ConfirmEmail(string userId, 
            string code)
        {
            if (userId == null || code == null)
            {
                return RedirectToAction("Login");
            }
            var user = await userManager.FindByIdAsync(userId);
            if (user == null)
            {
                return RedirectToAction("Login");
            }
            var result = await userManager.ConfirmEmailAsync(user, code);
            return RedirectToAction("Login");
        }

        [HttpGet]
        public IActionResult ForgotPassword()
        {
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> ForgotPassword(
            ForgotPasswordViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = await userManager.FindByEmailAsync(model.Email);
                if (user == null ||
                    !(await userManager.IsEmailConfirmedAsync(user)))
                {
                    return Content("Instructions for changing password have " +
                        "been sent on your email");
                }

                var code = await userManager
                    .GeneratePasswordResetTokenAsync(user);
                var callbackUrl = Url.Action("ResetPassword", "Account",
                    new { userId = user.Id, code = code },
                    protocol: HttpContext.Request.Scheme);
                await emailService.SendEmailAsync(model.Email, "Reset Password",
                $"To change password follow the link: " +
                $"<a href='{callbackUrl}'>link</a>");
                return Content("Instructions for changing your password have " +
                    "been sent to your email.");
            }
            return View(model);
        }

        [HttpGet]
        public IActionResult ResetPassword(string code = null)
        {
            return code == null ? View("Login") : View(
                new ResetPasswordViewModel
                {
                    Code = code
                });
        }

        [HttpPost]
        public async Task<IActionResult> ResetPassword(
            ResetPasswordViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }
            var user = await userManager.FindByEmailAsync(model.Email);
            if (user == null)
            {
                return View("ResetPasswordConfirmation");
            }
            var result = await userManager.ResetPasswordAsync(user,
                model.Code, model.Password);
            if (result.Succeeded)
            {
                return View("ResetPasswordConfirmation");
            }
            foreach (var error in result.Errors)
            {
                ModelState.AddModelError(string.Empty, error.Description);
            }
            return View(model);
        }

        [HttpGet]
        [Authorize]
        public IActionResult ChangePassword()
        {
            return View();
        }

        [HttpPost]
        [Authorize]
        public async Task<IActionResult> ChangePassword(
            ChangePasswordViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = await userManager.FindByIdAsync(userManager
                    .GetUserId(User));
                var result = await userManager.ChangePasswordAsync(user,
                    model.OldPassword, model.Password);
                if (result.Succeeded)
                    return RedirectToAction("Login");
                else
                {
                    foreach (var error in result.Errors)
                        ModelState.AddModelError("", error.Description);
                }
            }
            return View(model);
        }


        [HttpGet]
        [Authorize]
        public async Task<IActionResult> LogOut()
        {
            await signInManager.SignOutAsync();
            return RedirectToAction(nameof(Login));
        }

        [HttpGet]
        [Authorize]
        public async Task<IActionResult> UserInfo()
        {
            var user = await userManager.GetUserAsync(User);
            if (user == null)
                return NotFound();
            var model = new UserInfoViewModel 
            {
                Email = user.Email,
                UserName = user.UserName
            };
            return View(model);
        }
    }
}








留言

這個網誌中的熱門文章

何謂淨重(Net Weight)、皮重(Tare Weight)與毛重(Gross Weight)

Architecture(架構) 和 Framework(框架) 有何不同?_軟體設計前的事前規劃的藍圖概念

(2021年度)駕訓學科筆試準備題庫歸納分析_法規是非題